diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..e2aabb86 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +# Don't allow people to merge changes to these generated files, because the result +# may be invalid. You need to run "rush update" again. +pnpm-lock.yaml merge=binary +shrinkwrap.yaml merge=binary +npm-shrinkwrap.json merge=binary +yarn.lock merge=binary + +# Rush's JSON config files use JavaScript-style code comments. The rule below prevents pedantic +# syntax highlighters such as GitHub's from highlighting these comments as errors. Your text editor +# may also require a special configuration to allow comments in JSON. +# +# For more information, see this issue: https://github.com/microsoft/rushstack/issues/1088 +# +*.json linguist-language=JSON-with-Comments diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index 371e4779..00000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,32 +0,0 @@ -name-template: 'v$RESOLVED_VERSION 🌈' -tag-template: 'v$RESOLVED_VERSION' -categories: - - title: '🚀 Features' - labels: - - 'feature' - - 'enhancement' - - 'new' - - title: '🐛 Bug Fixes' - labels: - - 'fix' - - 'bugfix' - - 'bug' - - title: '🧰 Maintenance' - label: 'chore' -change-template: '- $TITLE @$AUTHOR (#$NUMBER)' -change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks. -version-resolver: - major: - labels: - - 'major' - minor: - labels: - - 'minor' - patch: - labels: - - 'patch' - default: patch -template: | - ## Changes - - $CHANGES \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..28f02017 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,266 @@ +name: Build Docker + +on: + pull_request: + push: + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.11 + uses: actions/setup-python@v3 + with: + python-version: '3.11' + - name: Install dependencies + run: | + python -m pip install --upgrade pip + if [ -f backend/requirements.txt ]; then pip install -r backend/requirements.txt; fi + pip install pytest + - name: Test + working-directory: ./backend/src + run: | + mkdir -p config + pytest + + version-info: + runs-on: ubuntu-latest + steps: + - name: If release + id: release + run: | + if [[${{ github.event_name }}== 'pull_request'] && [${{ github.event.pull_request.merged }} == true]] || \ + [[ ${{ github.event_name }} == 'push' && (${{ github.ref }} == *'alpha'* || ${{ github.ref }} == *'beta'*) ]]; then + echo "release=1" >> $GITHUB_OUTPUT + else + echo "release=0" >> $GITHUB_OUTPUT + fi + - name: If dev + id: dev + run: | + if [[ ${{ github.event_name }} == 'push' && (${{ github.ref }} == *'alpha'* || ${{ github.ref }} == *'beta'*) ]]; then + echo "dev=1" >> $GITHUB_OUTPUT + else + echo "dev=0" >> $GITHUB_OUTPUT + fi + - name: Check version + id: version + run: | + if [${{ github.event_name }} == 'pull_request' && ${{ github.event.pull_request.merged }} == true]; then + echo "version=${{ github.event.pull_request.title }}" >> $GITHUB_OUTPUT + git config --local user.email + git config --local user.name "github-actions" + git tag -a ${{ github.event.pull_request.title }} -m ${{ github.event.pull_request.body }} + git push origin ${{ github.event.pull_request.title }} + elif [[ ${{ github.event_name }} == 'push' && (${{ github.ref }} == *'alpha'* || ${{ github.ref }} == *'beta'*) ]]; then + echo "version=${{ github.ref_name }}" >> $GITHUB_OUTPUT + else + echo "version=Test" >> $GITHUB_OUTPUT + fi + - name: Check result + run: | + echo "release: ${{ steps.release.outputs.release }}" + echo "dev: ${{ steps.dev.outputs.dev }}" + echo "version: ${{ steps.version.outputs.version }}" + outputs: + release: ${{ steps.release.outputs.release }} + dev: ${{ steps.dev.outputs.dev }} + version: ${{ steps.version.outputs.version }} + + build-webui: + runs-on: ubuntu-latest + needs: [test, version-info] + if: ${{ needs.version-info.outputs.release == 1 || needs.version-info.outputs.dev == 1 }} + strategy: + matrix: + node-version: [18] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - uses: pnpm/action-setup@v2 + with: + version: 8 + + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + cache-dependency-path: webui/pnpm-lock.yaml + + - name: Install dependencies + run: cd webui && pnpm install + + - name: Build + run: | + cd webui && pnpm build + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: dist + path: webui/dist + + build-docker: + runs-on: ubuntu-latest + needs: [build-webui, version-info] + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Create Version info via tag + working-directory: ./backend/src + run: | + echo ${{ needs.version-info.outputs.version }} + echo "VERSION='${{ needs.version-info.outputs.version }}'" >> module/__version__.py + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + id: buildx + uses: docker/setup-buildx-action@v2 + + - name: Docker metadata main + if: ${{ needs.version-info.outputs.release == 1 && needs.version-info.outputs.dev != 1 }} + id: meta + uses: docker/metadata-action@v4 + with: + images: | + estrellaxd/auto_bangumi + ghcr.io/${{ github.repository }} + tags: | + type=semver,pattern=${{ needs.version-info.outputs.version }} + type=raw,value=latest + + - name: Docker metadata dev + if: ${{ needs.version-info.outputs.dev == 1 }} + id: meta-dev + uses: docker/metadata-action@v4 + with: + images: | + estrellaxd/auto_bangumi + ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ needs.version-info.outputs.version }} + type=raw,value=dev-latest + + - name: Login to DockerHub + if: ${{ needs.version-info.outputs.release == 1 }} + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Login to ghcr.io + if: ${{ needs.version-info.outputs.release == 1 }} + uses: docker/login-action@v2 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.ACCESS_TOKEN }} + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: dist + path: backend/src/dist + + - name: Build and push + if: ${{ needs.version-info.outputs.release == 1 && needs.version-info.outputs.dev != 1 }} + uses: docker/build-push-action@v4 + with: + context: . + builder: ${{ steps.buildx.output.name }} + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: ${{ github.event_name == 'push' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha, scope=${{ github.workflow }} + cache-to: type=gha, scope=${{ github.workflow }} + + - name: Build and push dev + if: ${{ needs.version-info.outputs.dev == 1 }} + uses: docker/build-push-action@v4 + with: + context: . + builder: ${{ steps.buildx.output.name }} + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: ${{ github.event_name == 'push' }} + tags: ${{ steps.meta-dev.outputs.tags }} + labels: ${{ steps.meta-dev.outputs.labels }} + cache-from: type=gha, scope=${{ github.workflow }} + cache-to: type=gha, scope=${{ github.workflow }} + + - name: Build test + if: ${{ needs.version-info.outputs.release == 0 }} + uses: docker/build-push-action@v4 + with: + context: . + builder: ${{ steps.buildx.output.name }} + platforms: linux/amd64,linux/arm64,linux/arm/v7 + push: false + tags: estrellaxd/auto_bangumi:test + cache-from: type=gha, scope=${{ github.workflow }} + cache-to: type=gha, scope=${{ github.workflow }} + + release: + runs-on: ubuntu-latest + needs: [build-docker, version-info] + if: ${{ needs.version-info.outputs.release == 1 }} + outputs: + url: ${{ steps.release.outputs.url }} + version: ${{ needs.version-info.outputs.version }} + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: dist + path: webui/dist + + - name: Zip webui + run: | + cd webui && ls -al && tree && zip -r dist.zip dist + + - name: Generate Release info + id: release-info + run: | + if ${{ needs.version-info.outputs.dev == 1 }}; then + echo "version=🌙${{ needs.version-info.outputs.version }}" >> $GITHUB_OUTPUT + echo "pre_release=true" >> $GITHUB_OUTPUT + else + echo "version=🌟${{ needs.version-info.outputs.version }}" >> $GITHUB_OUTPUT + echo "pre_release=false" >> $GITHUB_OUTPUT + fi + - name: Release + id: release + uses: softprops/action-gh-release@v1 + with: + tag_name: ${{ needs.version-info.outputs.version }} + name: ${{ steps.release-info.outputs.version }} + body: ${{ github.event.pull_request.body }} + draft: false + prerelease: ${{ steps.release-info.outputs.pre_release == 'true' }} + files: | + webui/dist.zip + env: + GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} + + + telegram: + runs-on: ubuntu-latest + needs: [release] + steps: + - name: send telegram message on push + uses: appleboy/telegram-action@master + with: + to: ${{ secrets.TELEGRAM_TO }} + token: ${{ secrets.TELEGRAM_TOKEN }} + message: | + New release: ${{ needs.release.outputs.version }} + Link: ${{ needs.release.outputs.url }} diff --git a/.github/workflows/dev-latest.yml b/.github/workflows/dev-latest.yml deleted file mode 100644 index eed5d029..00000000 --- a/.github/workflows/dev-latest.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Build Docker(dev) - -on: - push: - tags: - - '\d+\.\d+\.\d+-beta\d+' - - '\d+\.\d+-beta\d+' - - '\d+\.\d+-alpha\d+' - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.11 - uses: actions/setup-python@v3 - with: - python-version: "3.11" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - pip install pytest - - name: Test - working-directory: ./src - run: | - mkdir -p config - pytest - - dev-latest: - runs-on: ubuntu-latest - needs: [test] - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Create Version info - working-directory: ./src - run: | - echo "VERSION = '$GITHUB_REF_NAME'" > module/__version__.py - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Docker metadata - id: meta - uses: docker/metadata-action@v4 - with: - images: | - estrellaxd/auto_bangumi - ghcr.io/${{ github.repository }} - tags: | - type=raw,value=${{ github.ref_name }} - type=raw,value=dev-latest - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Login to ghcr.io - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ACCESS_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v3 - with: - context: . - push: true - tags: ${{ steps.meta.outputs.tags }} - file: Dockerfile - - generate_release: - runs-on: ubuntu-latest - needs: [test] - steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Generate Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.ref_name }} - name: 🌙${{ github.ref_name }} - draft: true - prerelease: true - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} - diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml deleted file mode 100644 index fdd527da..00000000 --- a/.github/workflows/docker.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: Build Docker - -on: - pull_request: - push: - tags: - - '\d+\.\d+\.\d+' - - '\d+\.\d+' - -jobs: - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Set up Python 3.11 - uses: actions/setup-python@v3 - with: - python-version: "3.11" - - name: Install dependencies - run: | - python -m pip install --upgrade pip - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - pip install pytest - - name: Test - working-directory: ./backend/src - run: | - mkdir -p config - pytest - - - build: - runs-on: ubuntu-latest - needs: [test] - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Create Version info - working-directory: ./backend/src - run: | - echo "VERSION = '$GITHUB_REF_NAME'" > module/__version__.py - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - id: buildx - uses: docker/setup-buildx-action@v2 - - - name: Docker metadata - id: meta - uses: docker/metadata-action@v4 - with: - images: | - ghcr.io/estrellaxd/auto_bangumi - estrellaxd/auto_bangumi - ghcr.io/${{ github.repository }} - tags: | - type=semver,pattern={{version}} - type=raw,value=latest - - - name: Login to DockerHub - if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKER_HUB_USERNAME }} - password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - - - name: Login to ghcr.io - if: ${{ github.event_name == 'push' }} - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.ACCESS_TOKEN }} - - - name: Build and push - uses: docker/build-push-action@v4 - with: - context: . - builder: ${{ steps.buildx.output.name }} - platforms: linux/amd64,linux/arm64,linux/arm/v7 - push: ${{ github.event_name == 'push' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - cache-from: type=gha, scope=${{ github.workflow }} - cache-to: type=gha, scope=${{ github.workflow }} diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml deleted file mode 100644 index afc1b051..00000000 --- a/.github/workflows/pull-request.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Create Pull Request - -on: - push: - tags: - - '\d+\.\d+\.\d+' - - '\d+\.\d+' - -jobs: - create-pull-request: - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Generate pull request body - id: pr - run: | - echo "docs/changelog/${{ github.ref }}.md" - - name: Create Pull Request - uses: peter-evans/create-pull-request@v3 - with: - token: ${{ secrets.ACCESS_TOKEN }} - commit-message: 'chore: release ${{ github.ref }}' - title: 'chore: release ${{ github.ref }}' - body: | - ${{ steps.pr.outputs.body }} - branch: release/${{ github.ref }} - base: main - labels: release - draft: false - branch-suffix: timestamp - delete-branch: false \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index cc2acdc5..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Generate Release Draft - -on: - pull_request: - types: - - closed - branches: - - main - -jobs: - check_pr_title: - if: > - github.event.pull_request.merged == true && - github.event.pull_request.base.ref == 'main' - runs-on: ubuntu-latest - outputs: - version_pr: ${{ steps.check.outputs.version_pr }} - steps: - - name: Check if PR title is version - id: check - run: | - if [[ "${{ github.event.pull_request.title }}" =~ ^([0-9]+\.[0-9]+\.[0-9]+)$ ]]; then - echo "::set-output name=version_pr::true" - else - echo "::set-output name=version_pr::false" - fi - - generate_release_draft: - needs: check_pr_title - if: - needs.check_pr_title.outputs.version_pr == 'true' - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Generate Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ github.event.pull_request.title }} - name: 🌟${{ github.event.pull_request.title }} - body: ${{ github.event.pull_request.body }} - draft: false - prerelease: false - env: - GITHUB_TOKEN: ${{ secrets.ACCESS_TOKEN }} diff --git a/.github/workflows/telegram.yml b/.github/workflows/telegram.yml deleted file mode 100644 index c3a50131..00000000 --- a/.github/workflows/telegram.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: Telegram Notification - -on: - release: - types: [published] - -jobs: - telegram: - runs-on: ubuntu-latest - steps: - - name: send telegram message on push - uses: appleboy/telegram-action@master - with: - to: ${{ secrets.TELEGRAM_TO }} - token: ${{ secrets.TELEGRAM_TOKEN }} - message: | - New release: ${{ github.event.release.title }} - Link: ${{ github.event.release.html_url }} \ No newline at end of file diff --git a/.gitignore b/.gitignore index 2fba0a13..34d4906b 100644 --- a/.gitignore +++ b/.gitignore @@ -121,7 +121,6 @@ celerybeat.pid # Environments .idea -.vscode .env .venv env/ @@ -162,6 +161,8 @@ cython_debug/ #.idea/ # Custom +# +# backend /backend/src/test.py /backend/src/module/run_debug.sh @@ -169,11 +170,46 @@ cython_debug/ /backend/src/module/__version__.py /backend/src/data/ -/backend/src/module/conf/config_dev.ini +/src/module/conf/config_dev.ini test.* .run /backend/src/templates/ /backend/src/config/ -/backend/src/debuger.py +/src/debuger.py /backend/src/dist.zip +/pyrightconfig.json + +# webui +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist.zip +dist-ssr +*.local +dev-dist + +# Editor directories and files +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json + +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +# vitepress +/docs/.vitepress/cache/ diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 3d0bec7f..00000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "docs/wiki"] - path = docs/wiki - url = https://github.com/EstrellaXD/Auto_Bangumi.wiki.git diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 00000000..b3db48e8 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,18 @@ +{ + "recommendations": [ + // https://marketplace.visualstudio.com/items?itemName=antfu.unocss + "antfu.unocss", + // https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag + "formulahendry.auto-rename-tag", + // https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker + "streetsidesoftware.code-spell-checker", + // https://marketplace.visualstudio.com/items?itemName=naumovs.color-highlight + "naumovs.color-highlight", + // https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance + "ms-python.vscode-pylance", + // https://marketplace.visualstudio.com/items?itemName=ms-python.python + "ms-python.python", + // https://marketplace.visualstudio.com/items?itemName=vue.volar + "vue.volar" + ] +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..c8358720 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,20 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "name": "Dev Backend", + "type": "python", + "request": "launch", + "cwd": "${workspaceFolder}/backend/src", + "program": "main.py", + "env": { + "HOST": "127.0.0.1", + }, + "console": "integratedTerminal", + "justMyCode": true + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..5d6b2455 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,19 @@ +{ + "files.associations": { + "settings.json": "json5", + "launch.json": "json5", + "extensions.json": "json5", + "tsconfig.json": "json5", + "tsconfig.*.json": "json5", + }, + "[markdown]": { + "editor.wordWrap": "off", + }, + "python.venvPath": "./backend/venv", + "cSpell.words": [ + "Bangumi", + "fastapi", + "mikan", + "starlette" + ], +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..6834d93c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,47 @@ +# [3.1] - 2023-08 + +- 合并了后端和前端仓库,优化了项目目录 +- 优化了版本发布流程。 +- Wiki 迁移至 Vitepress,地址:https://autobangumi.org + +## Backend + +### Features + +- 新增 `RSS Engine` 模块,从现在起,AB 可以自主对 RSS 进行更新支持 `RSS` 订阅并且发送种子给下载器。 + - 现在支持多个聚合 RSS 订阅源,可以通过 `RSS Engine` 模块进行管理。 + - 支持下载去重功能,重复的订阅的种子不会被下载。 + - 增加手动刷新 API,可以手动刷新 RSS 订阅。 + - 新增 RSS 订阅管理 API。 +- 新增 `Search Engine`模块,可以通过关键词搜索种子并解析成收集或者订阅任务。 + - 插件化的搜索引擎,可以通过插件的方式添加新的搜索目标,目前支持 `mikan`、`dmhy` 和 `nyaa` +- 新增对字幕组的特异性规则,可以针对不同的字幕组进行单独设置。 +- 新增 IPv6 监听支持,需要在环境变量中设置 `IPV6=1`。 +- API 新增批量操作,可以批量管理规则和 RSS 订阅。 + +### Changes + +- 数据库结构变更,更换为 `sqlmodel` 管理数据库。 +- 新增版本管理,可以无缝更新软件数据。 +- 调整 API 格式,更加统一。 +- 增加 API 返回语言选项。 +- 增加数据库 mock test。 +- 优化代码。 + +### Bugfixes + +- 修复了一些小问题。 +- 增加了一些大问题。 + +## Frontend + +### Features + +- 增加 `i18n` 支持,目前支持 `zh-CN` 和 `en-US`。 +- 增加 pwa 支持。 +- 增加 RSS 管理页面。 +- 增加搜索顶栏。 + +### Changes + +- 调整一些 UI 细节。 \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index dd4d7534..9d66f04d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,8 @@ # syntax=docker/dockerfile:1 -FROM alpine:3.18 AS APP +FROM alpine:3.18 -ENV S6_SERVICES_GRACETIME=30000 \ - S6_KILL_GRACETIME=60000 \ - S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \ - S6_SYNC_DISKS=1 \ - TERM="xterm" \ - HOME="/ab" \ - LANG="C.UTF-8" \ +ENV LANG="C.UTF-8" \ TZ=Asia/Shanghai \ PUID=1000 \ PGID=1000 \ @@ -16,39 +10,33 @@ ENV S6_SERVICES_GRACETIME=30000 \ WORKDIR /app -COPY requirements.txt . -RUN apk add --no-cache \ +COPY backend/requirements.txt . +RUN set -ex && \ + apk add --no-cache \ bash \ - ca-certificates \ - coreutils \ - curl \ - jq \ - netcat-openbsd \ - procps-ng \ python3 \ py3-bcrypt \ py3-pip \ - s6-overlay \ + su-exec \ shadow \ + tini \ tzdata && \ - python3 -m pip install --upgrade pip && \ + python3 -m pip install --no-cache-dir --upgrade pip && \ sed -i '/bcrypt/d' requirements.txt && \ pip install --no-cache-dir -r requirements.txt && \ - # Download WebUI - curl -sL "https://github.com/Rewrite0/Auto_Bangumi_WebUI/releases/latest/download/dist.zip" | busybox unzip -q -d /app - && \ - mv /app/dist /app/templates && \ # Add user + mkdir -p /home/ab && \ addgroup -S ab -g 911 && \ - adduser -S ab -G ab -h /ab -s /bin/bash -u 911 && \ + adduser -S ab -G ab -h /home/ab -s /sbin/nologin -u 911 && \ # Clear rm -rf \ /root/.cache \ /tmp/* COPY --chmod=755 backend/src/. . -COPY --chmod=755 backend/src/docker / +COPY --chmod=755 entrypoint.sh /entrypoint.sh -ENTRYPOINT [ "/init" ] +ENTRYPOINT ["tini", "-g", "--", "/entrypoint.sh"] EXPOSE 7892 VOLUME [ "/app/config" , "/app/data" ] diff --git a/README.md b/README.md index a83b9c99..970937d8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@

- - + +

@@ -16,7 +16,7 @@ # 项目说明

- +

本项目是基于 [Mikan Project](https://mikanani.me)、[qBittorrent](https://qbittorrent.org) 的全自动追番整理下载工具。只需要在 [Mikan Project](https://mikanani.me) 上订阅番剧,就可以全自动追番。并且整理完成的名称和目录可以直接被 [Plex]()、[Jellyfin]() 等媒体库软件识别,无需二次刮削。 diff --git a/backend/.pre-commit-config.yaml b/backend/.pre-commit-config.yaml index daecff1d..c51713af 100644 --- a/backend/.pre-commit-config.yaml +++ b/backend/.pre-commit-config.yaml @@ -5,4 +5,4 @@ repos: - id: black language: python -# TODO: add ruff lint check before committing \ No newline at end of file +# TODO: add ruff lint check before committing. \ No newline at end of file diff --git a/backend/.vscode/settings.json b/backend/.vscode/settings.json new file mode 100644 index 00000000..24dec46e --- /dev/null +++ b/backend/.vscode/settings.json @@ -0,0 +1,8 @@ +{ + "python.formatting.provider": "none", + "python.formatting.blackPath": "black", + "editor.formatOnSave": true, + "[python]": { + "editor.defaultFormatter": "ms-python.black-formatter" + } +} diff --git a/backend/dev.sh b/backend/dev.sh new file mode 100755 index 00000000..4234c27d --- /dev/null +++ b/backend/dev.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# This script is used to run the development environment. + +python3 -m venv venv + +./venv/bin/python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements-dev.txt + +# install git-hooks for pre-commit before committing. +./venv/bin/pre-commit install + +cd src || exit + +CONFIG_DIR="config" + +if [ ! -d "$CONFIG_DIR" ]; then + echo "The directory '$CONFIG_DIR' is missing." + mkdir config +fi + +VERSION_FILE="module/__version__.py" + +if [ ! -f "$VERSION_FILE" ]; then + echo "The file '$VERSION_FILE' is missing." + echo "VERSION='DEV_VERSION'" >>"$VERSION_FILE" +fi + +../venv/bin/uvicorn main:app --reload --port 7892 diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 8342c4b9..b70f6a71 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,15 +1,15 @@ [tool.ruff] select = [ # pycodestyle(E): https://beta.ruff.rs/docs/rules/#pycodestyle-e-w - "E", + "E", # Pyflakes(F): https://beta.ruff.rs/docs/rules/#pyflakes-f - "F", + "F", # isort(I): https://beta.ruff.rs/docs/rules/#isort-i "I" ] ignore = [ # E501: https://beta.ruff.rs/docs/rules/line-too-long/ - 'E501', + 'E501', # F401: https://beta.ruff.rs/docs/rules/unused-import/ # avoid unused imports lint in `__init__.py` 'F401', diff --git a/backend/requirements-dev.txt b/backend/requirements-dev.txt new file mode 100644 index 00000000..8240495a --- /dev/null +++ b/backend/requirements-dev.txt @@ -0,0 +1,4 @@ +-r requirements.txt +ruff +black +pre-commit \ No newline at end of file diff --git a/backend/requirements.txt b/backend/requirements.txt new file mode 100644 index 00000000..0ac360cd --- /dev/null +++ b/backend/requirements.txt @@ -0,0 +1,28 @@ +anyio==3.7.0 +bs4==0.0.1 +certifi==2023.5.7 +charset-normalizer==3.1.0 +click==8.1.3 +fastapi==0.97.0 +h11==0.14.0 +idna==3.4 +pydantic~=1.10 +PySocks==1.7.1 +qbittorrent-api==2023.6.49 +requests==2.31.0 +six==1.16.0 +sniffio==1.3.0 +soupsieve==2.4.1 +typing_extensions==4.6.3 +urllib3==2.0.3 +uvicorn==0.22.0 +attrdict==2.0.1 +Jinja2==3.1.2 +python-dotenv==1.0.0 +python-jose==3.3.0 +passlib==1.7.4 +bcrypt==4.0.1 +python-multipart==0.0.6 +sqlmodel==0.0.8 +sse-starlette==1.6.5 +semver==3.0.1 diff --git a/backend/scripts/pip-lock-version.sh b/backend/scripts/pip-lock-version.sh new file mode 100755 index 00000000..676501a1 --- /dev/null +++ b/backend/scripts/pip-lock-version.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash + +# +# Usage: +# `bash scripts/pip-lock-version.sh` +# +# ```prompt +# Lock the library versions in `requirements.txt` to the current ones from `pip freeze` using shell script, +# but don't change any order in `requirements.txt` +# ``` +# + + +# Create a temporary requirements file using pip freeze +pip freeze > pip_freeze.log + +# Read the existing requirements.txt line by line +while IFS= read -r line +do + # Extract the library name without version + lib_name=$(echo $line | cut -d'=' -f1) + + # Find the corresponding library in the temporary requirements file + lib_line=$(grep "^$lib_name==" pip_freeze.log) + + # If the library is found, update the line + if [[ $lib_line ]] + then + echo $lib_line + else + echo $line + fi + +# Redirect the output to a new requirements file +done < requirements.txt > new_requirements.log + +# Remove the temporary requirements file +rm pip_freeze.log + +# Replace the old requirements file with the new one +mv new_requirements.log requirements.txt + diff --git a/backend/src/docker/etc/cont-init.d/010-old-compatible b/backend/src/docker/etc/cont-init.d/010-old-compatible deleted file mode 100644 index f6136488..00000000 --- a/backend/src/docker/etc/cont-init.d/010-old-compatible +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/with-contenv bash -# shellcheck shell=bash - -function __old_compatible { - - umask ${UMASK} - - if [ -f /config/bangumi.json ]; then - mv /config/bangumi.json /app/data/bangumi.json - fi - -} - -__old_compatible 2>&1 | sed "s#^#cont-init: info: $(realpath $0): &#g" \ No newline at end of file diff --git a/backend/src/docker/etc/cont-init.d/020-fixuser b/backend/src/docker/etc/cont-init.d/020-fixuser deleted file mode 100644 index 76cf9163..00000000 --- a/backend/src/docker/etc/cont-init.d/020-fixuser +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/with-contenv bash -# shellcheck shell=bash - -function __fixuser { - - groupmod -o -g "${PGID}" ab - usermod -o -u "${PUID}" ab - - chown ab:ab -R /app /ab - -} - -__fixuser 2>&1 | sed "s#^#cont-init: info: $(realpath $0): &#g" \ No newline at end of file diff --git a/backend/src/docker/etc/services.d/auto_bangumi/finish b/backend/src/docker/etc/services.d/auto_bangumi/finish deleted file mode 100644 index b1ccd97a..00000000 --- a/backend/src/docker/etc/services.d/auto_bangumi/finish +++ /dev/null @@ -1,4 +0,0 @@ -#!/usr/bin/with-contenv bash -# shellcheck shell=bash - -pkill -f 'python3 main.py' \ No newline at end of file diff --git a/backend/src/docker/etc/services.d/auto_bangumi/notification-fd b/backend/src/docker/etc/services.d/auto_bangumi/notification-fd deleted file mode 100644 index e440e5c8..00000000 --- a/backend/src/docker/etc/services.d/auto_bangumi/notification-fd +++ /dev/null @@ -1 +0,0 @@ -3 \ No newline at end of file diff --git a/backend/src/docker/etc/services.d/auto_bangumi/run b/backend/src/docker/etc/services.d/auto_bangumi/run deleted file mode 100644 index ea0d1347..00000000 --- a/backend/src/docker/etc/services.d/auto_bangumi/run +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/with-contenv bash -# shellcheck shell=bash - -umask ${UMASK} - -if [ -f /app/config/config.json ]; then - AB_PORT=$(jq '.program.webui_port' /app/config/config.json) -elif [ -f /app/config/config_dev.json ]; then - AB_PORT=$(jq '.program.webui_port' /app/config/config_dev.json) -else - AB_PORT=7892 -fi - -exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${AB_PORT}" \ - cd /app s6-setuidgid ab python3 main.py \ No newline at end of file diff --git a/backend/src/icon b/backend/src/icon deleted file mode 100644 index b5ddfb0a..00000000 --- a/backend/src/icon +++ /dev/null @@ -1,8 +0,0 @@ - _ ____ _ - /\ | | | _ \ (_) - / \ _ _| |_ ___ | |_) | __ _ _ __ __ _ _ _ _ __ ___ _ - / /\ \| | | | __/ _ \| _ < / _` | '_ \ / _` | | | | '_ ` _ \| | - / ____ \ |_| | || (_) | |_) | (_| | | | | (_| | |_| | | | | | | | - /_/ \_\__,_|\__\___/|____/ \__,_|_| |_|\__, |\__,_|_| |_| |_|_| - __/ | - |___/ \ No newline at end of file diff --git a/backend/src/main.py b/backend/src/main.py index 3ccd2649..581d2173 100644 --- a/backend/src/main.py +++ b/backend/src/main.py @@ -1,10 +1,15 @@ import os - import logging -import uvicorn -from module.api import router -from module.conf import settings, setup_logger +import uvicorn +from fastapi import FastAPI, Request +from fastapi.responses import FileResponse, HTMLResponse, RedirectResponse +from fastapi.staticfiles import StaticFiles +from fastapi.templating import Jinja2Templates +from module.api import v1 +from module.api.proxy import router as proxy_router +from module.conf import settings, setup_logger, VERSION +from starlette.types import ASGIApp setup_logger(reset=True) logger = logging.getLogger(__name__) @@ -22,10 +27,82 @@ uvicorn_logging_config = { }, } + +def create_app() -> FastAPI: + app = FastAPI() + + # mount routers + app.include_router(v1, prefix="/api") + app.include_router(proxy_router) + + return app + + +app = create_app() + + +if VERSION != "DEV_VERSION": + app.mount("/assets", StaticFiles(directory="dist/assets"), name="assets") + app.mount("/images", StaticFiles(directory="dist/images"), name="images") + # app.mount("/icons", StaticFiles(directory="dist/icons"), name="icons") + templates = Jinja2Templates(directory="dist") + + # Resource + # @app.get("/favicon.svg", tags=["html"]) + # def favicon(): + # return FileResponse("dist/favicon.svg") + # + # @app.get("/AutoBangumi.svg", tags=["html"]) + # def logo(): + # return FileResponse("dist/AutoBangumi.svg") + # + # @app.get("/favicon-light.svg", tags=["html"]) + # def favicon_light(): + # return FileResponse("dist/favicon-light.svg") + # + # @app.get("/robots.txt", tags=["html"]) + # def robots(): + # return FileResponse("dist/robots.txt") + # + # @app.get("/manifest.webmanifest", tags=["html"]) + # def manifest(): + # return FileResponse("dist/manifest.webmanifest") + # + # @app.get("/sw.js", tags=["html"]) + # def sw(): + # return FileResponse("dist/sw.js") + + @app.get("/{path:path}") + def html(request: Request, path: str): + files = os.listdir("dist") + if path in files: + return FileResponse(f"dist/{path}") + else: + context = {"request": request} + return templates.TemplateResponse("index.html", context) + + # HTML Response + # @app.get("/{path:path}", response_class=HTMLResponse, tags=["html"]) + # def index(request: Request, path: str): + # print(request) + # print(path) + # context = {"request": request} + # return templates.TemplateResponse("index.html", context) + +else: + + @app.get("/", status_code=302, tags=["html"]) + def index(): + return RedirectResponse("/docs") + + if __name__ == "__main__": - host = "::" if os.getenv("IPV6") else "0.0.0.0" + if os.getenv("IPV6"): + host = "::" + else: + host = os.getenv("HOST", "0.0.0.0") uvicorn.run( - router, + app, host=host, port=settings.program.webui_port, log_config=uvicorn_logging_config, diff --git a/backend/src/module/ab_decorator/__init__.py b/backend/src/module/ab_decorator/__init__.py index 3c29c227..85b84082 100644 --- a/backend/src/module/ab_decorator/__init__.py +++ b/backend/src/module/ab_decorator/__init__.py @@ -1,6 +1,8 @@ import logging -import time import threading +import time + +from .timeout import timeout logger = logging.getLogger(__name__) lock = threading.Lock() diff --git a/backend/src/module/ab_decorator/timeout.py b/backend/src/module/ab_decorator/timeout.py new file mode 100644 index 00000000..32f3a985 --- /dev/null +++ b/backend/src/module/ab_decorator/timeout.py @@ -0,0 +1,23 @@ +import signal + + +def timeout(seconds): + def decorator(func): + def handler(signum, frame): + raise TimeoutError("Function timed out.") + + def wrapper(*args, **kwargs): + # 设置信号处理程序,当超时时触发TimeoutError异常 + signal.signal(signal.SIGALRM, handler) + signal.alarm(seconds) # 设置alarm定时器 + + try: + result = func(*args, **kwargs) + finally: + signal.alarm(0) # 取消alarm定时器 + + return result + + return wrapper + + return decorator diff --git a/backend/src/module/api/__init__.py b/backend/src/module/api/__init__.py index e90516af..38999e4d 100644 --- a/backend/src/module/api/__init__.py +++ b/backend/src/module/api/__init__.py @@ -1 +1,21 @@ -from .web import router +from fastapi import APIRouter + +from .auth import router as auth_router +from .bangumi import router as bangumi_router +from .config import router as config_router +from .log import router as log_router +from .program import router as program_router +from .rss import router as rss_router +from .search import router as search_router + +__all__ = "v1" + +# API 1.0 +v1 = APIRouter(prefix="/v1") +v1.include_router(auth_router) +v1.include_router(log_router) +v1.include_router(program_router) +v1.include_router(bangumi_router) +v1.include_router(config_router) +v1.include_router(rss_router) +v1.include_router(search_router) diff --git a/backend/src/module/api/auth.py b/backend/src/module/api/auth.py index de255dd3..410ab036 100644 --- a/backend/src/module/api/auth.py +++ b/backend/src/module/api/auth.py @@ -1,58 +1,66 @@ from datetime import timedelta -from fastapi import Depends, HTTPException, status +from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordRequestForm +from fastapi.responses import JSONResponse, Response -from module.security import ( - create_access_token, +from .response import u_response + +from module.models.user import User, UserUpdate +from module.models import APIResponse +from module.security.api import ( + auth_user, get_current_user, update_user_info, - auth_user, + active_user ) -from module.models.user import User +from module.security.jwt import create_access_token -from .program import router +router = APIRouter(prefix="/auth", tags=["auth"]) -@router.post("/api/v1/auth/login", response_model=dict, tags=["auth"]) -async def login(form_data: OAuth2PasswordRequestForm = Depends()): - username = form_data.username - password = form_data.password - auth_user(username, password) - token = create_access_token(data={"sub": username}, expires_delta=timedelta(days=1)) - - return {"access_token": token, "token_type": "bearer", "expire": 86400} - - -@router.get("/api/v1/auth/refresh_token", response_model=dict, tags=["auth"]) -async def refresh(current_user: User = Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" +@router.post("/login", response_model=dict) +async def login(response: Response, form_data=Depends(OAuth2PasswordRequestForm)): + user = User(username=form_data.username, password=form_data.password) + resp = auth_user(user) + if resp.status: + token = create_access_token( + data={"sub": user.username}, expires_delta=timedelta(days=1) ) - token = create_access_token(data={"sub": current_user.username}) - return {"access_token": token, "token_type": "bearer", "expire": 86400} + response.set_cookie(key="token", value=token, httponly=True, max_age=86400) + return {"access_token": token, "token_type": "bearer"} + return u_response(resp) + +@router.get("/refresh_token", response_model=dict, dependencies=[Depends(get_current_user)]) +async def refresh(response: Response): + token = create_access_token( + data={"sub": active_user[0]}, expires_delta=timedelta(days=1) + ) + response.set_cookie(key="token", value=token, httponly=True, max_age=86400) + return {"access_token": token, "token_type": "bearer"} -@router.get("/api/v1/auth/logout", response_model=dict, tags=["auth"]) -async def logout(current_user: User = Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" +@router.get("/logout", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def logout(response: Response): + active_user.clear() + response.delete_cookie(key="token") + return JSONResponse( + status_code=200, + content={"msg_en": "Logout successfully.", "msg_zh": "登出成功。"}, + ) + + +@router.post("/update", response_model=dict, dependencies=[Depends(get_current_user)]) +async def update_user( + user_data: UserUpdate, response: Response +): + old_user = active_user[0] + if update_user_info(user_data, old_user): + token = create_access_token(data={"sub": old_user}, expires_delta=timedelta(days=1)) + response.set_cookie( + key="token", + value=token, + httponly=True, + max_age=86400, ) - return {"message": "logout success"} - - -@router.post("/api/v1/auth/update", response_model=dict, tags=["auth"]) -async def update_user(user_data: User, current_user: User = Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - if update_user_info(user_data, current_user): - return { - "message": "update success", - "access_token": create_access_token({"sub": user_data.username}), - "token_type": "bearer", - "expire": 86400, - } + return {"access_token": token, "token_type": "bearer", "message": "update success"} diff --git a/backend/src/module/api/bangumi.py b/backend/src/module/api/bangumi.py index 611e9c43..a96c22c2 100644 --- a/backend/src/module/api/bangumi.py +++ b/backend/src/module/api/bangumi.py @@ -1,95 +1,85 @@ -import logging - -from fastapi import Depends, HTTPException, status +from fastapi import APIRouter, Depends from fastapi.responses import JSONResponse -from .log import router +from .response import u_response -from module.models import BangumiData from module.manager import TorrentManager -from module.security import get_current_user +from module.models import Bangumi, BangumiUpdate, APIResponse +from module.security.api import get_current_user, UNAUTHORIZED -logger = logging.getLogger(__name__) +router = APIRouter(prefix="/bangumi", tags=["bangumi"]) -@router.get( - "/api/v1/bangumi/getAll", tags=["bangumi"], response_model=list[BangumiData] -) -async def get_all_data(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - return torrent.search_all() +def str_to_list(data: Bangumi): + data.filter = data.filter.split(",") + data.rss_link = data.rss_link.split(",") + return data -@router.get( - "/api/v1/bangumi/getData/{bangumi_id}", tags=["bangumi"], response_model=BangumiData -) -async def get_data(bangumi_id: str, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - return torrent.search_one(bangumi_id) +@router.get("/get/all", response_model=list[Bangumi], dependencies=[Depends(get_current_user)]) +async def get_all_data(): + with TorrentManager() as manager: + return manager.bangumi.search_all() -@router.post("/api/v1/bangumi/updateRule", tags=["bangumi"]) -async def update_rule(data: BangumiData, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - try: - return torrent.update_rule(data) - except Exception as e: - logger.error(f"Failed to update rule: {e}") - return JSONResponse(status_code=500, content={"message": "Failed"}) +@router.get("/get/{bangumi_id}", response_model=Bangumi, dependencies=[Depends(get_current_user)]) +async def get_data(bangumi_id: str): + with TorrentManager() as manager: + resp = manager.search_one(bangumi_id) + return resp -@router.delete("/api/v1/bangumi/deleteRule/{bangumi_id}", tags=["bangumi"]) -async def delete_rule( - bangumi_id: str, file: bool = False, current_user=Depends(get_current_user) +@router.patch("/update/{bangumi_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def update_rule( + bangumi_id: int, data: BangumiUpdate, ): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" + with TorrentManager() as manager: + resp = manager.update_rule(bangumi_id, data) + return u_response(resp) + + +@router.delete(path="/delete/{bangumi_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def delete_rule(bangumi_id: str, file: bool = False): + with TorrentManager() as manager: + resp = manager.delete_rule(bangumi_id, file) + return u_response(resp) + + +@router.delete(path="/delete/many/", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def delete_many_rule(bangumi_id: list, file: bool = False): + with TorrentManager() as manager: + for i in bangumi_id: + resp = manager.delete_rule(i, file) + return u_response(resp) + + +@router.delete(path="/disable/{bangumi_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def disable_rule(bangumi_id: str, file: bool = False): + with TorrentManager() as manager: + resp = manager.disable_rule(bangumi_id, file) + return u_response(resp) + + +@router.delete(path="/disable/many/", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def disable_many_rule(bangumi_id: list, file: bool = False): + with TorrentManager() as manager: + for i in bangumi_id: + resp = manager.disable_rule(i, file) + return u_response(resp) + + +@router.get(path="/enable/{bangumi_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def enable_rule(bangumi_id: str): + with TorrentManager() as manager: + resp = manager.enable_rule(bangumi_id) + return u_response(resp) + + +@router.get("/reset/all", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def reset_all(): + with TorrentManager() as manager: + manager.bangumi.delete_all() + return JSONResponse( + status_code=200, + content={"msg_en": "Reset all rules successfully.", "msg_zh": "重置所有规则成功。"}, ) - with TorrentManager() as torrent: - return torrent.delete_rule(bangumi_id, file) - - -@router.delete("/api/v1/bangumi/disableRule/{bangumi_id}", tags=["bangumi"]) -async def disable_rule( - bangumi_id: str, file: bool = False, current_user=Depends(get_current_user) -): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - return torrent.disable_rule(bangumi_id, file) - - -@router.get("/api/v1/bangumi/enableRule/{bangumi_id}", tags=["bangumi"]) -async def enable_rule(bangumi_id: str, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - return torrent.enable_rule(bangumi_id) - - -@router.get("/api/v1/bangumi/resetAll", tags=["bangumi"]) -async def reset_all(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - with TorrentManager() as torrent: - torrent.delete_all() - return JSONResponse(status_code=200, content={"message": "OK"}) diff --git a/backend/src/module/api/config.py b/backend/src/module/api/config.py index b034d9d0..3b307599 100644 --- a/backend/src/module/api/config.py +++ b/backend/src/module/api/config.py @@ -1,36 +1,35 @@ import logging -from fastapi import Depends, HTTPException, status - -from .bangumi import router +from fastapi import APIRouter, Depends +from fastapi.responses import JSONResponse from module.conf import settings -from module.models import Config -from module.security import get_current_user +from module.models import Config, APIResponse +from module.security.api import get_current_user, UNAUTHORIZED +router = APIRouter(prefix="/config", tags=["config"]) logger = logging.getLogger(__name__) -@router.get("/api/v1/getConfig", tags=["config"], response_model=Config) -async def get_config(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.get("/get", response_model=Config, dependencies=[Depends(get_current_user)]) +async def get_config(): return settings -@router.post("/api/v1/updateConfig", tags=["config"]) -async def update_config(config: Config, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.patch("/update", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def update_config(config: Config): try: settings.save(config_dict=config.dict()) settings.load() + # update_rss() logger.info("Config updated") - return {"message": "Success"} + return JSONResponse( + status_code=200, + content={"msg_en": "Update config successfully.", "msg_zh": "更新配置成功。"} + ) except Exception as e: logger.warning(e) - return {"message": "Failed to update config"} + return JSONResponse( + status_code=406, + content={"msg_en": "Update config failed.", "msg_zh": "更新配置失败。"} + ) diff --git a/backend/src/module/api/download.py b/backend/src/module/api/download.py deleted file mode 100644 index 6ce80569..00000000 --- a/backend/src/module/api/download.py +++ /dev/null @@ -1,54 +0,0 @@ -from fastapi import Depends, HTTPException, status - -from .config import router - -from module.models.api import * -from module.models import BangumiData -from module.manager import SeasonCollector -from module.rss import analyser -from module.security import get_current_user - - -@router.post("/api/v1/download/analysis", tags=["download"]) -async def analysis(link: RssLink, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - data = analyser.link_to_data(link.rss_link) - if data: - return data - else: - return {"status": "Failed to parse link"} - - -@router.post("/api/v1/download/collection", tags=["download"]) -async def download_collection( - data: BangumiData, current_user=Depends(get_current_user) -): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - if data: - with SeasonCollector() as collector: - if collector.collect_season(data, data.rss_link[0], proxy=True): - return {"status": "Success"} - else: - return {"status": "Failed to add torrent"} - else: - return {"status": "Failed to parse link"} - - -@router.post("/api/v1/download/subscribe", tags=["download"]) -async def subscribe(data: BangumiData, current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - if data: - with SeasonCollector() as collector: - collector.subscribe_season(data) - return {"status": "Success"} - else: - return {"status": "Failed to parse link"} diff --git a/backend/src/module/api/log.py b/backend/src/module/api/log.py index 8e7e65d7..04d1434d 100644 --- a/backend/src/module/api/log.py +++ b/backend/src/module/api/log.py @@ -1,34 +1,32 @@ -import os -from fastapi import Response, HTTPException, Depends, status - -from .auth import router +from fastapi import APIRouter, Depends, HTTPException, Response, status +from fastapi.responses import JSONResponse from module.conf import LOG_PATH -from module.security import get_current_user +from module.security.api import get_current_user, UNAUTHORIZED +from module.models import APIResponse + +router = APIRouter(prefix="/log", tags=["log"]) -@router.get("/api/v1/log", tags=["log"]) -async def get_log(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - if os.path.isfile(LOG_PATH): +@router.get("", response_model=str, dependencies=[Depends(get_current_user)]) +async def get_log(): + if LOG_PATH.exists(): with open(LOG_PATH, "rb") as f: return Response(f.read(), media_type="text/plain") else: return Response("Log file not found", status_code=404) -@router.get("/api/v1/log/clear", tags=["log"]) -async def clear_log(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" +@router.get("/clear", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def clear_log(): + if LOG_PATH.exists(): + LOG_PATH.write_text("") + return JSONResponse( + status_code=200, + content={"msg_en": "Log cleared successfully.", "msg_zh": "日志清除成功。"}, ) - if os.path.isfile(LOG_PATH): - with open(LOG_PATH, "w") as f: - f.write("") - return {"status": "ok"} else: - return Response("Log file not found", status_code=404) + return JSONResponse( + status_code=406, + content={"msg_en": "Log file not found.", "msg_zh": "日志文件未找到。"}, + ) diff --git a/backend/src/module/api/program.py b/backend/src/module/api/program.py index d8cf46c4..691bd149 100644 --- a/backend/src/module/api/program.py +++ b/backend/src/module/api/program.py @@ -1,16 +1,20 @@ -import signal import logging import os +import signal -from fastapi import HTTPException, status, Depends -from fastapi import FastAPI +from fastapi import APIRouter, Depends, HTTPException +from fastapi.responses import JSONResponse + +from .response import u_response from module.core import Program -from module.security import get_current_user +from module.models import APIResponse +from module.conf import VERSION +from module.security.api import get_current_user, UNAUTHORIZED logger = logging.getLogger(__name__) program = Program() -router = FastAPI() +router = APIRouter(tags=["program"]) @router.on_event("startup") @@ -23,82 +27,73 @@ async def shutdown(): program.stop() -@router.get("/api/v1/restart", tags=["program"]) -async def restart(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.get("/restart", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def restart(): try: - program.restart() - return {"status": "ok"} + resp = program.restart() + return u_response(resp) except Exception as e: logger.debug(e) logger.warning("Failed to restart program") - raise HTTPException(status_code=500, detail="Failed to restart program") - - -@router.get("/api/v1/start", tags=["program"]) -async def start(current_user=Depends(get_current_user)): - if not current_user: raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" + status_code=500, + detail={ + "msg_en": "Failed to restart program.", + "msg_zh": "重启程序失败。", + } ) + + +@router.get("/start", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def start(): try: - return program.start() + resp = program.start() + return u_response(resp) except Exception as e: logger.debug(e) logger.warning("Failed to start program") - raise HTTPException(status_code=500, detail="Failed to start program") - - -@router.get("/api/v1/stop", tags=["program"]) -async def stop(current_user=Depends(get_current_user)): - if not current_user: raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" + status_code=500, + detail={ + "msg_en": "Failed to start program.", + "msg_zh": "启动程序失败。", + } ) - return program.stop() -@router.get("/api/v1/status", tags=["program"]) -async def status(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.get("/stop", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def stop(): + return u_response(program.stop()) + + +@router.get("/status", response_model=dict, dependencies=[Depends(get_current_user)]) +async def program_status(): if not program.is_running: - return {"status": "stop"} + return { + "status": False, + "version": VERSION, + "first_run": program.first_run, + } else: - return {"status": "running"} + return { + "status": True, + "version": VERSION, + "first_run": program.first_run, + } -@router.get("/api/v1/shutdown", tags=["program"]) -async def shutdown_program(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.get("/shutdown", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def shutdown_program(): program.stop() logger.info("Shutting down program...") os.kill(os.getpid(), signal.SIGINT) - return {"status": "ok"} + return JSONResponse( + status_code=200, + content={"msg_en": "Shutdown program successfully.", "msg_zh": "关闭程序成功。"}, + ) # Check status -@router.get("/api/v1/check/downloader", tags=["check"]) -async def check_downloader_status(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) +@router.get("/check/downloader", tags=["check"], response_model=bool, dependencies=[Depends(get_current_user)]) +async def check_downloader_status(): return program.check_downloader() - - -@router.get("/api/v1/check/rss", tags=["check"]) -async def check_rss_status(current_user=Depends(get_current_user)): - if not current_user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - return program.check_analyser() diff --git a/backend/src/module/api/proxy.py b/backend/src/module/api/proxy.py index c9b43b8a..2b50cbdf 100644 --- a/backend/src/module/api/proxy.py +++ b/backend/src/module/api/proxy.py @@ -1,14 +1,14 @@ -import re import logging +import re -from fastapi.responses import Response +from fastapi import APIRouter from fastapi.exceptions import HTTPException - -from .download import router +from fastapi.responses import Response from module.conf import settings from module.network import RequestContent +router = APIRouter() logger = logging.getLogger(__name__) diff --git a/backend/src/module/api/response.py b/backend/src/module/api/response.py new file mode 100644 index 00000000..b0a2dc26 --- /dev/null +++ b/backend/src/module/api/response.py @@ -0,0 +1,14 @@ +from fastapi.responses import JSONResponse +from fastapi.exceptions import HTTPException + +from module.models.response import ResponseModel + + +def u_response(response_model: ResponseModel): + return JSONResponse( + status_code=response_model.status_code, + content={ + "msg_en": response_model.msg_en, + "msg_zh": response_model.msg_zh, + }, + ) \ No newline at end of file diff --git a/backend/src/module/api/rss.py b/backend/src/module/api/rss.py new file mode 100644 index 00000000..2244c67d --- /dev/null +++ b/backend/src/module/api/rss.py @@ -0,0 +1,150 @@ +from fastapi import APIRouter, Depends +from fastapi.responses import JSONResponse + +from .response import u_response + +from module.models import RSSItem, RSSUpdate, Torrent, APIResponse, Bangumi +from module.rss import RSSEngine, RSSAnalyser +from module.security.api import get_current_user, UNAUTHORIZED +from module.downloader import DownloadClient +from module.manager import SeasonCollector + + +router = APIRouter(prefix="/rss", tags=["rss"]) + + +@router.get(path="", response_model=list[RSSItem], dependencies=[Depends(get_current_user)]) +async def get_rss(): + with RSSEngine() as engine: + return engine.rss.search_all() + + +@router.post(path="/add", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def add_rss(rss: RSSItem): + with RSSEngine() as engine: + result = engine.add_rss(rss.url, rss.name, rss.aggregate, rss.parser) + return u_response(result) + + +@router.post(path="/enable/many", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def enable_many_rss(rss_ids: list[int], ): + with RSSEngine() as engine: + result = engine.enable_list(rss_ids) + return u_response(result) + + +@router.delete(path="/delete/{rss_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def delete_rss(rss_id: int): + with RSSEngine() as engine: + if engine.rss.delete(rss_id): + return JSONResponse( + status_code=200, + content={"msg_en": "Delete RSS successfully.", "msg_zh": "删除 RSS 成功。"}, + ) + else: + return JSONResponse( + status_code=406, + content={"msg_en": "Delete RSS failed.", "msg_zh": "删除 RSS 失败。"}, + ) + + +@router.post(path="/delete/many", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def delete_many_rss(rss_ids: list[int], ): + with RSSEngine() as engine: + result = engine.delete_list(rss_ids) + return u_response(result) + + +@router.patch(path="/disable/{rss_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def disable_rss(rss_id: int): + with RSSEngine() as engine: + if engine.rss.disable(rss_id): + return JSONResponse( + status_code=200, + content={"msg_en": "Disable RSS successfully.", "msg_zh": "禁用 RSS 成功。"}, + ) + else: + return JSONResponse( + status_code=406, + content={"msg_en": "Disable RSS failed.", "msg_zh": "禁用 RSS 失败。"}, + ) + + +@router.post(path="/disable/many", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def disable_many_rss(rss_ids: list[int]): + with RSSEngine() as engine: + result = engine.disable_list(rss_ids) + return u_response(result) + + +@router.patch(path="/update/{rss_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def update_rss( + rss_id: int, data: RSSUpdate, current_user=Depends(get_current_user) +): + if not current_user: + raise UNAUTHORIZED + with RSSEngine() as engine: + if engine.rss.update(rss_id, data): + return JSONResponse( + status_code=200, + content={"msg_en": "Update RSS successfully.", "msg_zh": "更新 RSS 成功。"}, + ) + else: + return JSONResponse( + status_code=406, + content={"msg_en": "Update RSS failed.", "msg_zh": "更新 RSS 失败。"}, + ) + + +@router.get(path="/refresh/all", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def refresh_all(): + with RSSEngine() as engine, DownloadClient() as client: + engine.refresh_rss(client) + return JSONResponse( + status_code=200, + content={"msg_en": "Refresh all RSS successfully.", "msg_zh": "刷新 RSS 成功。"}, + ) + + +@router.get(path="/refresh/{rss_id}", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def refresh_rss(rss_id: int): + with RSSEngine() as engine, DownloadClient() as client: + engine.refresh_rss(client, rss_id) + return JSONResponse( + status_code=200, + content={"msg_en": "Refresh RSS successfully.", "msg_zh": "刷新 RSS 成功。"}, + ) + + +@router.get(path="/torrent/{rss_id}", response_model=list[Torrent], dependencies=[Depends(get_current_user)]) +async def get_torrent(rss_id: int, ): + with RSSEngine() as engine: + return engine.get_rss_torrents(rss_id) + + +# Old API +analyser = RSSAnalyser() + + +@router.post("/analysis", response_model=Bangumi, dependencies=[Depends(get_current_user)]) +async def analysis(rss: RSSItem): + data = analyser.link_to_data(rss) + if isinstance(data, Bangumi): + return data + else: + return u_response(data) + + +@router.post("/collect", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def download_collection(data: Bangumi): + with SeasonCollector() as collector: + resp = collector.collect_season(data, data.rss_link) + return u_response(resp) + + +@router.post("/subscribe", response_model=APIResponse, dependencies=[Depends(get_current_user)]) +async def subscribe(data: Bangumi): + with SeasonCollector() as collector: + resp = collector.subscribe_season(data) + return u_response(resp) + diff --git a/backend/src/module/api/search.py b/backend/src/module/api/search.py new file mode 100644 index 00000000..3ad90984 --- /dev/null +++ b/backend/src/module/api/search.py @@ -0,0 +1,31 @@ +from fastapi import APIRouter, Query, Depends +from sse_starlette.sse import EventSourceResponse + +from module.searcher import SearchTorrent, SEARCH_CONFIG +from module.security.api import get_current_user, UNAUTHORIZED +from module.models import Bangumi + + +router = APIRouter(prefix="/search", tags=["search"]) + + +@router.get("/bangumi", response_model=list[Bangumi], dependencies=[Depends(get_current_user)]) +async def search_torrents( + site: str = "mikan", + keywords: str = Query(None) +): + """ + Server Send Event for per Bangumi item + """ + if not keywords: + return [] + keywords = keywords.split(" ") + with SearchTorrent() as st: + return EventSourceResponse( + content=st.analyse_keyword(keywords=keywords, site=site), + ) + + +@router.get("/provider", response_model=list[str], dependencies=[Depends(get_current_user)]) +async def search_provider(): + return list(SEARCH_CONFIG.keys()) diff --git a/backend/src/module/api/web.py b/backend/src/module/api/web.py deleted file mode 100644 index 37e6afcf..00000000 --- a/backend/src/module/api/web.py +++ /dev/null @@ -1,38 +0,0 @@ -from fastapi import Request -from fastapi.responses import HTMLResponse, RedirectResponse, FileResponse -from fastapi.staticfiles import StaticFiles -from fastapi.templating import Jinja2Templates - -from .proxy import router - -from module.conf import VERSION - - -if VERSION != "DEV_VERSION": - router.mount("/assets", StaticFiles(directory="templates/assets"), name="assets") - templates = Jinja2Templates(directory="templates") - - # Resource - @router.get("/favicon.svg", tags=["html"]) - def favicon(): - return FileResponse("templates/favicon.svg") - - @router.get("/AutoBangumi.svg", tags=["html"]) - def logo(): - return FileResponse("templates/AutoBangumi.svg") - - @router.get("/favicon-light.svg", tags=["html"]) - def favicon_light(): - return FileResponse("templates/favicon-light.svg") - - # HTML Response - @router.get("/{full_path:path}", response_class=HTMLResponse, tags=["html"]) - def index(request: Request): - context = {"request": request} - return templates.TemplateResponse("index.html", context) - -else: - - @router.get("/", status_code=302, tags=["html"]) - def index(): - return RedirectResponse("/docs") diff --git a/backend/src/module/checker/checker.py b/backend/src/module/checker/checker.py index 474637f6..09fc222c 100644 --- a/backend/src/module/checker/checker.py +++ b/backend/src/module/checker/checker.py @@ -1,9 +1,13 @@ -import os.path +import logging +import requests +from pathlib import Path +from module.conf import settings, VERSION from module.downloader import DownloadClient -from module.network import RequestContent -from module.conf import settings from module.models import Config +from module.update import version_check + +logger = logging.getLogger(__name__) class Checker: @@ -24,30 +28,50 @@ class Checker: else: return False - @staticmethod - def check_downloader() -> bool: - with DownloadClient() as client: - if client.authed: - return True - else: - return False - - @staticmethod - def check_torrents() -> bool: - with RequestContent() as req: - try: - torrents = req.get_torrents(settings.rss_link, retry=2) - if torrents: - return True - except AttributeError: - link = f"https://mikanani.me/RSS/MyBangumi?token={settings.rss_parser.token}" - if req.get_torrents(link): - return True - return False - @staticmethod def check_first_run() -> bool: if settings.dict() == Config().dict(): return True else: return False + + @staticmethod + def check_version() -> bool: + return version_check() + + @staticmethod + def check_database() -> bool: + db_path = Path("data/data.db") + if not db_path.exists(): + return False + else: + return True + + @staticmethod + def check_downloader() -> bool: + try: + url = f"http://{settings.downloader.host}" if "://" not in settings.downloader.host else f"{settings.downloader.host}" + response = requests.get(url, timeout=2) + if settings.downloader.type in response.text.lower(): + with DownloadClient() as client: + if client.authed: + return True + else: + return False + else: + return False + except requests.exceptions.ReadTimeout: + logger.error("[Checker] Downloader connect timeout.") + return False + except requests.exceptions.ConnectionError: + logger.error("[Checker] Downloader connect failed.") + return False + except Exception as e: + logger.error(f"[Checker] Downloader connect failed: {e}") + return False + + +if __name__ == "__main__": + # print(Checker().check_downloader()) + requests.get("http://162.200.20.1", timeout=2) + diff --git a/backend/src/module/conf/__init__.py b/backend/src/module/conf/__init__.py index 04b72fd9..9a1b7aef 100644 --- a/backend/src/module/conf/__init__.py +++ b/backend/src/module/conf/__init__.py @@ -1,8 +1,12 @@ -from .log import setup_logger, LOG_PATH -from .config import VERSION, settings +from pathlib import Path +from .config import VERSION, settings +from .log import LOG_PATH, setup_logger +from .search_provider import SEARCH_CONFIG TMDB_API = "32b19d6a05b512190a056fa4e747cbbc" -DATA_PATH = "data/data.db" +DATA_PATH = "sqlite:///data/data.db" +LEGACY_DATA_PATH = Path("data/data.json") +VERSION_PATH = Path("config/version.info") PLATFORM = "Windows" if "\\" in settings.downloader.path else "Unix" diff --git a/backend/src/module/conf/config.py b/backend/src/module/conf/config.py index 90503783..1a9cf1f4 100644 --- a/backend/src/module/conf/config.py +++ b/backend/src/module/conf/config.py @@ -1,31 +1,35 @@ import json -import os import logging +import os +from pathlib import Path + from dotenv import load_dotenv -from .const import ENV_TO_ATTR from module.models.config import Config +from .const import ENV_TO_ATTR + logger = logging.getLogger(__name__) +CONFIG_ROOT = Path("config") + try: from module.__version__ import VERSION - - if VERSION == "DEV_VERSION": - logger.info("Can't find version info, use DEV_VERSION instead") - CONFIG_PATH = "config/config_dev.json" - else: - CONFIG_PATH = f"config/config.json" except ImportError: logger.info("Can't find version info, use DEV_VERSION instead") VERSION = "DEV_VERSION" - CONFIG_PATH = "config/config_dev.json" + +CONFIG_PATH = ( + CONFIG_ROOT / "config_dev.json" + if VERSION == "DEV_VERSION" + else CONFIG_ROOT / "config.json" +).resolve() class Settings(Config): def __init__(self): super().__init__() - if os.path.exists(CONFIG_PATH): + if CONFIG_PATH.exists(): self.load() self.save() else: @@ -36,7 +40,7 @@ class Settings(Config): config = json.load(f) config_obj = Config.parse_obj(config) self.__dict__.update(config_obj.__dict__) - logger.info(f"Config loaded") + logger.info("Config loaded") def save(self, config_dict: dict | None = None): if not config_dict: @@ -49,14 +53,6 @@ class Settings(Config): self.__load_from_env() self.save() - @property - def rss_link(self) -> str: - if "://" not in self.rss_parser.custom_url: - return f"https://{self.rss_parser.custom_url}/RSS/MyBangumi?token={self.rss_parser.token}" - return ( - f"{self.rss_parser.custom_url}/RSS/MyBangumi?token={self.rss_parser.token}" - ) - def __load_from_env(self): config_dict = self.dict() for key, section in ENV_TO_ATTR.items(): @@ -73,7 +69,7 @@ class Settings(Config): config_dict[key][attr_name] = self.__val_from_env(env, attr) config_obj = Config.parse_obj(config_dict) self.__dict__.update(config_obj.__dict__) - logger.info(f"Config loaded from env") + logger.info("Config loaded from env") @staticmethod def __val_from_env(env: str, attr: tuple): @@ -83,5 +79,9 @@ class Settings(Config): else: return os.environ[env] + @property + def group_rules(self): + return self.__dict__["group_rules"] + settings = Settings() diff --git a/backend/src/module/conf/const.py b/backend/src/module/conf/const.py index e8b5634f..c48409d7 100644 --- a/backend/src/module/conf/const.py +++ b/backend/src/module/conf/const.py @@ -1,6 +1,5 @@ # -*- encoding: utf-8 -*- -from urllib.parse import urlparse, parse_qs - +from urllib.parse import parse_qs, urlparse DEFAULT_SETTINGS = { "program": { diff --git a/backend/src/module/conf/log.py b/backend/src/module/conf/log.py index 8ba45ce1..2d567424 100644 --- a/backend/src/module/conf/log.py +++ b/backend/src/module/conf/log.py @@ -1,17 +1,19 @@ -import os import logging +from pathlib import Path from .config import settings -LOG_PATH = "data/log.txt" +LOG_ROOT = Path("data") +LOG_PATH = LOG_ROOT / "log.txt" def setup_logger(level: int = logging.INFO, reset: bool = False): level = logging.DEBUG if settings.log.debug_enable else level - if not os.path.isdir("data"): - os.mkdir("data") - if reset and os.path.isfile(LOG_PATH): - os.remove(LOG_PATH) + LOG_ROOT.mkdir(exist_ok=True) + + if reset and LOG_PATH.exists(): + LOG_PATH.unlink(missing_ok=True) + logging.addLevelName(logging.DEBUG, "DEBUG:") logging.addLevelName(logging.INFO, "INFO:") logging.addLevelName(logging.WARNING, "WARNING:") diff --git a/backend/src/module/conf/search_provider.py b/backend/src/module/conf/search_provider.py new file mode 100644 index 00000000..610c7f55 --- /dev/null +++ b/backend/src/module/conf/search_provider.py @@ -0,0 +1,23 @@ +from pathlib import Path +from module.utils import json_config + +DEFAULT_PROVIDER = { + "mikan": "https://mikanani.me/RSS/Search?searchstr=%s", + "nyaa": "https://nyaa.si/?page=rss&q=%s&c=0_0&f=0", + "dmhy": "http://dmhy.org/topics/rss/rss.xml?keyword=%s" +} + +PROVIDER_PATH = Path("config/search_provider.json") + + +def load_provider(): + if PROVIDER_PATH.exists(): + return json_config.load(PROVIDER_PATH) + else: + json_config.save(PROVIDER_PATH, DEFAULT_PROVIDER) + return DEFAULT_PROVIDER + + +SEARCH_CONFIG = load_provider() + + diff --git a/backend/src/module/core/program.py b/backend/src/module/core/program.py index 466eed90..fa7ee3ec 100644 --- a/backend/src/module/core/program.py +++ b/backend/src/module/core/program.py @@ -1,20 +1,30 @@ import logging -from .sub_thread import RenameThread, RSSThread -from .rss_feed import add_rss_feed +from module.conf import VERSION, settings +from module.update import data_migration, from_30_to_31, start_up, first_run +from module.models import ResponseModel -from module.conf import settings, VERSION -from module.update import data_migration +from .sub_thread import RenameThread, RSSThread logger = logging.getLogger(__name__) +figlet = r""" + _ ____ _ + /\ | | | _ \ (_) + / \ _ _| |_ ___ | |_) | __ _ _ __ __ _ _ _ _ __ ___ _ + / /\ \| | | | __/ _ \| _ < / _` | '_ \ / _` | | | | '_ ` _ \| | + / ____ \ |_| | || (_) | |_) | (_| | | | | (_| | |_| | | | | | | | + /_/ \_\__,_|\__\___/|____/ \__,_|_| |_|\__, |\__,_|_| |_| |_|_| + __/ | + |___/ +""" + class Program(RenameThread, RSSThread): @staticmethod def __start_info(): - with open("icon", "r") as f: - for line in f.readlines(): - logger.info(line.strip("\n")) + for line in figlet.splitlines(): + logger.info(line.strip("\n")) logger.info( f"Version {VERSION} Author: EstrellaXD Twitter: https://twitter.com/Estrella_Pan" ) @@ -23,42 +33,78 @@ class Program(RenameThread, RSSThread): def startup(self): self.__start_info() - if self.first_run: - logger.info("First run detected, please configure the program in webui.") + if not self.database: + first_run() + logger.info("[Core] No db file exists, create database file.") return {"status": "First run detected."} if self.legacy_data: logger.info( - "Legacy data detected, starting data migration, please wait patiently." + "[Core] Legacy data detected, starting data migration, please wait patiently." ) data_migration() + elif self.version_update: + # Update database + from_30_to_31() + logger.info("[Core] Database updated.") self.start() def start(self): - if self.first_run: - return {"status": "Not ready to start."} self.stop_event.clear() settings.load() if self.downloader_status: if self.enable_renamer: self.rename_start() if self.enable_rss: - add_rss_feed() self.rss_start() logger.info("Program running.") - return {"status": "Program started."} + return ResponseModel( + status=True, + status_code=200, + msg_en="Program started.", + msg_zh="程序启动成功。", + ) else: - return {"status": "Can't connect to downloader. Program not paused."} + self.stop_event.set() + logger.warning("Program failed to start.") + return ResponseModel( + status=False, + status_code=406, + msg_en="Program failed to start.", + msg_zh="程序启动失败。", + ) def stop(self): if self.is_running: self.stop_event.set() self.rename_stop() self.rss_stop() - return {"status": "Program stopped."} + return ResponseModel( + status=True, + status_code=200, + msg_en="Program stopped.", + msg_zh="程序停止成功。", + ) else: - return {"status": "Program is not running."} + return ResponseModel( + status=False, + status_code=406, + msg_en="Program is not running.", + msg_zh="程序未运行。", + ) def restart(self): self.stop() self.start() - return {"status": "Program restarted."} + return ResponseModel( + status=True, + status_code=200, + msg_en="Program restarted.", + msg_zh="程序重启成功。", + ) + + def update_database(self): + if not self.version_update: + return {"status": "No update found."} + else: + start_up() + return {"status": "Database updated."} diff --git a/backend/src/module/core/rss_feed.py b/backend/src/module/core/rss_feed.py deleted file mode 100644 index e1f14653..00000000 --- a/backend/src/module/core/rss_feed.py +++ /dev/null @@ -1,34 +0,0 @@ -import logging - -from module.downloader import DownloadClient -from module.conf import settings - -logger = logging.getLogger(__name__) - - -def add_rss_feed(): - with DownloadClient() as client: - # Check Feed if exists - add = True - remove = False - feeds = client.get_rss_feed() - for item_path, value in feeds.items(): - if value.url == settings.rss_link: - add = False - break - elif item_path == "Mikan_RSS": - remove = True - if remove: - client.remove_rss_feed("Mikan_RSS") - logger.info("Remove Old RSS Feed: Mikan_RSS") - # Add Feed - if add: - client.add_rss_feed(settings.rss_link) - logger.info(f"Add RSS Feed: {settings.rss_link}") - - -if __name__ == "__main__": - from module.conf import setup_logger - - setup_logger() - add_rss_feed() diff --git a/backend/src/module/core/status.py b/backend/src/module/core/status.py index de42599b..5e55e42a 100644 --- a/backend/src/module/core/status.py +++ b/backend/src/module/core/status.py @@ -1,8 +1,8 @@ -import os.path -import threading import asyncio +import threading from module.checker import Checker +from module.conf import LEGACY_DATA_PATH class ProgramStatus(Checker): @@ -31,12 +31,6 @@ class ProgramStatus(Checker): self._downloader_status = self.check_downloader() return self._downloader_status - @property - def torrents_status(self): - if not self._torrents_status: - self._torrents_status = self.check_torrents() - return self._torrents_status - @property def enable_rss(self): return self.check_analyser() @@ -51,4 +45,12 @@ class ProgramStatus(Checker): @property def legacy_data(self): - return os.path.exists("data/data.json") + return LEGACY_DATA_PATH.exists() + + @property + def version_update(self): + return not self.check_version() + + @property + def database(self): + return self.check_database() diff --git a/backend/src/module/core/sub_thread.py b/backend/src/module/core/sub_thread.py index 122bf744..4968a2c2 100644 --- a/backend/src/module/core/sub_thread.py +++ b/backend/src/module/core/sub_thread.py @@ -1,14 +1,13 @@ import threading import time -from .status import ProgramStatus - -from module.rss import analyser +from module.conf import settings from module.downloader import DownloadClient from module.manager import Renamer, eps_complete from module.notification import PostNotification -from module.database import BangumiDatabase -from module.conf import settings +from module.rss import RSSAnalyser, RSSEngine + +from .status import ProgramStatus class RSSThread(ProgramStatus): @@ -17,21 +16,17 @@ class RSSThread(ProgramStatus): self._rss_thread = threading.Thread( target=self.rss_loop, ) + self.analyser = RSSAnalyser() def rss_loop(self): - with DownloadClient() as client: - client.init_downloader() while not self.stop_event.is_set(): - # Analyse RSS - with BangumiDatabase() as db: - new_data = analyser.rss_to_data(rss_link=settings.rss_link, database=db) - if new_data: - db.insert_list(new_data) - bangumi_list = db.not_added() - if bangumi_list: - with DownloadClient() as client: - client.set_rules(bangumi_list) - db.update_list(bangumi_list) + with DownloadClient() as client, RSSEngine() as engine: + # Analyse RSS + rss_list = engine.rss.search_aggregate() + for rss in rss_list: + self.analyser.rss_to_data(rss, engine) + # Run RSS Engine + engine.refresh_rss(client) if settings.bangumi_manage.eps_complete: eps_complete() self.stop_event.wait(settings.program.rss_time) diff --git a/backend/src/module/database/__init__.py b/backend/src/module/database/__init__.py index c5d59b08..87d8425a 100644 --- a/backend/src/module/database/__init__.py +++ b/backend/src/module/database/__init__.py @@ -1 +1,2 @@ -from .bangumi import BangumiDatabase +from .combine import Database +from .engine import engine diff --git a/backend/src/module/database/bangumi.py b/backend/src/module/database/bangumi.py index 9d2a530c..d9d3db09 100644 --- a/backend/src/module/database/bangumi.py +++ b/backend/src/module/database/bangumi.py @@ -1,155 +1,110 @@ import logging -from module.database.connector import DataConnector -from module.models import BangumiData -from module.ab_decorator import locked +from sqlmodel import Session, select, delete, or_, and_ +from sqlalchemy.sql import func +from typing import Optional + +from module.models import Bangumi, BangumiUpdate logger = logging.getLogger(__name__) -class BangumiDatabase(DataConnector): - def __init__(self): - super().__init__() - self.__table_name = "bangumi" +class BangumiDatabase: + def __init__(self, session: Session): + self.session = session - def update_table(self): - db_data = self.__data_to_db(BangumiData()) - self._update_table(self.__table_name, db_data) + def add(self, data: Bangumi): + self.session.add(data) + self.session.commit() + logger.debug(f"[Database] Insert {data.official_title} into database.") - @staticmethod - def __data_to_db(data: BangumiData) -> dict: - db_data = data.dict() - for key, value in db_data.items(): - if isinstance(value, bool): - db_data[key] = int(value) - elif isinstance(value, list): - db_data[key] = ",".join(value) - return db_data + def add_all(self, datas: list[Bangumi]): + self.session.add_all(datas) + self.session.commit() + logger.debug(f"[Database] Insert {len(datas)} bangumi into database.") - @staticmethod - def __db_to_data(db_data: dict) -> BangumiData: - for key, item in db_data.items(): - if isinstance(item, int): - if key not in ["id", "offset", "season", "year"]: - db_data[key] = bool(item) - elif key in ["filter", "rss_link"]: - db_data[key] = item.split(",") - return BangumiData(**db_data) - - def __fetch_data(self) -> list[BangumiData]: - values = self._cursor.fetchall() - if values is None: - return [] - keys = [x[0] for x in self._cursor.description] - dict_data = [dict(zip(keys, value)) for value in values] - return [self.__db_to_data(x) for x in dict_data] - - def insert(self, data: BangumiData): - if self.__check_exist(data): - self.update_one(data) + def update(self, data: Bangumi | BangumiUpdate, _id: int = None) -> bool: + if _id and isinstance(data, BangumiUpdate): + db_data = self.session.get(Bangumi, _id) + elif isinstance(data, Bangumi): + db_data = self.session.get(Bangumi, data.id) else: - db_data = self.__data_to_db(data) - db_data["id"] = self.gen_id() - self._insert(db_data=db_data, table_name=self.__table_name) - logger.debug(f"[Database] Insert {data.official_title} into database.") + return False + if not db_data: + return False + bangumi_data = data.dict(exclude_unset=True) + for key, value in bangumi_data.items(): + setattr(db_data, key, value) + self.session.add(db_data) + self.session.commit() + self.session.refresh(db_data) + logger.debug(f"[Database] Update {data.official_title}") + return True - def insert_list(self, data: list[BangumiData]): - _id = self.gen_id() - for i, item in enumerate(data): - item.id = _id + i - data_list = [self.__data_to_db(x) for x in data] - self._insert_list(data_list=data_list, table_name=self.__table_name) - logger.debug(f"[Database] Insert {len(data)} bangumi into database.") + def update_all(self, datas: list[Bangumi]): + self.session.add_all(datas) + self.session.commit() + logger.debug(f"[Database] Update {len(datas)} bangumi.") - def update_one(self, data: BangumiData) -> bool: - db_data = self.__data_to_db(data) - return self._update(db_data=db_data, table_name=self.__table_name) - - def update_list(self, data: list[BangumiData]): - data_list = [self.__data_to_db(x) for x in data] - self._update_list(data_list=data_list, table_name=self.__table_name) - - @locked def update_rss(self, title_raw, rss_set: str): # Update rss and added - self._cursor.execute( - """ - UPDATE bangumi - SET rss_link = :rss_link, added = 0 - WHERE title_raw = :title_raw - """, - {"rss_link": rss_set, "title_raw": title_raw}, - ) - self._conn.commit() + statement = select(Bangumi).where(Bangumi.title_raw == title_raw) + bangumi = self.session.exec(statement).first() + bangumi.rss_link = rss_set + bangumi.added = False + self.session.add(bangumi) + self.session.commit() + self.session.refresh(bangumi) logger.debug(f"[Database] Update {title_raw} rss_link to {rss_set}.") def update_poster(self, title_raw, poster_link: str): - self._cursor.execute( - """ - UPDATE bangumi - SET poster_link = :poster_link - WHERE title_raw = :title_raw - """, - {"poster_link": poster_link, "title_raw": title_raw}, - ) - self._conn.commit() + statement = select(Bangumi).where(Bangumi.title_raw == title_raw) + bangumi = self.session.exec(statement).first() + bangumi.poster_link = poster_link + self.session.add(bangumi) + self.session.commit() + self.session.refresh(bangumi) logger.debug(f"[Database] Update {title_raw} poster_link to {poster_link}.") - def delete_one(self, _id: int) -> bool: - self._cursor.execute( - """ - DELETE FROM bangumi WHERE id = :id - """, - {"id": _id}, - ) - self._conn.commit() + def delete_one(self, _id: int): + statement = select(Bangumi).where(Bangumi.id == _id) + bangumi = self.session.exec(statement).first() + self.session.delete(bangumi) + self.session.commit() logger.debug(f"[Database] Delete bangumi id: {_id}.") - return self._cursor.rowcount == 1 def delete_all(self): - self._delete_all(self.__table_name) + statement = delete(Bangumi) + self.session.exec(statement) + self.session.commit() - def search_all(self) -> list[BangumiData]: - dict_data = self._search_datas(self.__table_name) - return [self.__db_to_data(x) for x in dict_data] + def search_all(self) -> list[Bangumi]: + statement = select(Bangumi) + return self.session.exec(statement).all() - def search_id(self, _id: int) -> BangumiData | None: - condition = {"id": _id} - dict_data = self._search_data(table_name=self.__table_name, condition=condition) - if dict_data is None: + def search_id(self, _id: int) -> Optional[Bangumi]: + statement = select(Bangumi).where(Bangumi.id == _id) + bangumi = self.session.exec(statement).first() + if bangumi is None: + logger.warning(f"[Database] Cannot find bangumi id: {_id}.") return None - return self.__db_to_data(dict_data) - - def search_official_title(self, official_title: str) -> BangumiData | None: - dict_data = self._search_data( - table_name=self.__table_name, condition={"official_title": official_title} - ) - if dict_data is None: - return None - return self.__db_to_data(dict_data) + else: + logger.debug(f"[Database] Find bangumi id: {_id}.") + return self.session.exec(statement).first() def match_poster(self, bangumi_name: str) -> str: - data = self._cursor.execute( - """ - SELECT poster_link FROM bangumi - WHERE INSTR(:official_title, official_title) > 0 - """, - {"official_title": bangumi_name}, - ).fetchone() - if not data: + # Use like to match + statement = select(Bangumi).where( + func.instr(bangumi_name, Bangumi.official_title) > 0 + ) + data = self.session.exec(statement).first() + if data: + return data.poster_link + else: return "" - poster_link = data[0] - if not poster_link: - return "" - return poster_link def match_list(self, torrent_list: list, rss_link: str) -> list: - # Match title_raw in database - keys = ["title_raw", "rss_link", "poster_link"] - match_datas = self._search_datas( - table_name=self.__table_name, - keys=keys, - ) + match_datas = self.search_all() if not match_datas: return torrent_list # Match title @@ -157,71 +112,51 @@ class BangumiDatabase(DataConnector): while i < len(torrent_list): torrent = torrent_list[i] for match_data in match_datas: - if match_data.get("title_raw") in torrent.name: - if rss_link not in match_data.get("rss_link"): - match_data["rss_link"] += f",{rss_link}" - self.update_rss( - match_data.get("title_raw"), match_data.get("rss_link") - ) - if not match_data.get("poster_link"): - self.update_poster( - match_data.get("title_raw"), torrent.poster_link - ) + if match_data.title_raw in torrent.name: + if rss_link not in match_data.rss_link: + match_data.rss_link += f",{rss_link}" + self.update_rss(match_data.title_raw, match_data.rss_link) + # if not match_data.poster_link: + # self.update_poster(match_data.title_raw, torrent.poster_link) torrent_list.pop(i) break else: i += 1 return torrent_list - def not_complete(self) -> list[BangumiData]: + def match_torrent(self, torrent_name: str) -> Optional[Bangumi]: + statement = select(Bangumi).where( + and_( + func.instr(torrent_name, Bangumi.title_raw) > 0, + Bangumi.deleted == False, + ) + ) + return self.session.exec(statement).first() + + def not_complete(self) -> list[Bangumi]: # Find eps_complete = False - condition = {"eps_collect": 0} - dict_data = self._search_datas( - table_name=self.__table_name, - condition=condition, + condition = select(Bangumi).where(Bangumi.eps_collect == False) + datas = self.session.exec(condition).all() + return datas + + def not_added(self) -> list[Bangumi]: + conditions = select(Bangumi).where( + or_( + Bangumi.added == 0, Bangumi.rule_name is None, Bangumi.save_path is None + ) ) - return [self.__db_to_data(x) for x in dict_data] + datas = self.session.exec(conditions).all() + return datas - def not_added(self) -> list[BangumiData]: - self._cursor.execute( - """ - SELECT * FROM bangumi - WHERE added = 0 OR rule_name IS NULL OR save_path IS NULL - """ - ) - return self.__fetch_data() + def disable_rule(self, _id: int): + statement = select(Bangumi).where(Bangumi.id == _id) + bangumi = self.session.exec(statement).first() + bangumi.deleted = True + self.session.add(bangumi) + self.session.commit() + self.session.refresh(bangumi) + logger.debug(f"[Database] Disable rule {bangumi.title_raw}.") - def gen_id(self) -> int: - self._cursor.execute( - """ - SELECT id FROM bangumi ORDER BY id DESC LIMIT 1 - """ - ) - data = self._cursor.fetchone() - if data is None: - return 1 - return data[0] + 1 - - def __check_exist(self, data: BangumiData): - self._cursor.execute( - """ - SELECT * FROM bangumi WHERE official_title = :official_title - """, - {"official_title": data.official_title}, - ) - values = self._cursor.fetchone() - if values is None: - return False - return True - - def __check_list_exist(self, data_list: list[BangumiData]): - for data in data_list: - if self.__check_exist(data): - return True - return False - - -if __name__ == "__main__": - with BangumiDatabase() as db: - name = "久保同学不放过我(2023)" - print(db.match_poster(name)) + def search_rss(self, rss_link: str) -> list[Bangumi]: + statement = select(Bangumi).where(func.instr(rss_link, Bangumi.rss_link) > 0) + return self.session.exec(statement).all() diff --git a/backend/src/module/database/combine.py b/backend/src/module/database/combine.py new file mode 100644 index 00000000..41550134 --- /dev/null +++ b/backend/src/module/database/combine.py @@ -0,0 +1,44 @@ +from sqlmodel import Session, SQLModel + +from .rss import RSSDatabase +from .torrent import TorrentDatabase +from .bangumi import BangumiDatabase +from .user import UserDatabase +from .engine import engine as e + +from module.models import User, Bangumi + + +class Database(Session): + def __init__(self, engine=e): + self.engine = engine + super().__init__(engine) + self.rss = RSSDatabase(self) + self.torrent = TorrentDatabase(self) + self.bangumi = BangumiDatabase(self) + self.user = UserDatabase(self) + + def create_table(self): + SQLModel.metadata.create_all(self.engine) + + def drop_table(self): + SQLModel.metadata.drop_all(self.engine) + + def migrate(self): + # Run migration online + bangumi_data = self.bangumi.search_all() + user_data = self.exec("SELECT * FROM user").all() + readd_bangumi = [] + for bangumi in bangumi_data: + dict_data = bangumi.dict() + del dict_data["id"] + readd_bangumi.append(Bangumi(**dict_data)) + self.drop_table() + self.create_table() + self.commit() + bangumi_data = self.bangumi.search_all() + self.bangumi.add_all(readd_bangumi) + self.add(User(**user_data[0])) + self.commit() + + diff --git a/backend/src/module/database/connector.py b/backend/src/module/database/connector.py deleted file mode 100644 index d4dbea56..00000000 --- a/backend/src/module/database/connector.py +++ /dev/null @@ -1,175 +0,0 @@ -import os -import sqlite3 -import logging - - -from module.conf import DATA_PATH - -logger = logging.getLogger(__name__) - - -class DataConnector: - def __init__(self): - # Create folder if not exists - if not os.path.exists(os.path.dirname(DATA_PATH)): - os.makedirs(os.path.dirname(DATA_PATH)) - self._conn = sqlite3.connect(DATA_PATH) - self._cursor = self._conn.cursor() - - def _update_table(self, table_name: str, db_data: dict): - columns = ", ".join( - [ - f"{key} {self.__python_to_sqlite_type(value)}" - for key, value in db_data.items() - ] - ) - create_table_sql = f"CREATE TABLE IF NOT EXISTS {table_name} ({columns});" - self._cursor.execute(create_table_sql) - self._cursor.execute(f"PRAGMA table_info({table_name})") - existing_columns = { - column_info[1]: column_info for column_info in self._cursor.fetchall() - } - for key, value in db_data.items(): - if key not in existing_columns: - insert_column = self.__python_to_sqlite_type(value) - if value is None: - value = "NULL" - add_column_sql = f"ALTER TABLE {table_name} ADD COLUMN {key} {insert_column} DEFAULT {value};" - self._cursor.execute(add_column_sql) - self._conn.commit() - logger.debug(f"Create / Update table {table_name}.") - - def _insert(self, table_name: str, db_data: dict): - columns = ", ".join(db_data.keys()) - values = ", ".join([f":{key}" for key in db_data.keys()]) - self._cursor.execute( - f"INSERT INTO {table_name} ({columns}) VALUES ({values})", db_data - ) - self._conn.commit() - - def _insert_list(self, table_name: str, data_list: list[dict]): - columns = ", ".join(data_list[0].keys()) - values = ", ".join([f":{key}" for key in data_list[0].keys()]) - self._cursor.executemany( - f"INSERT INTO {table_name} ({columns}) VALUES ({values})", data_list - ) - self._conn.commit() - - def _select(self, keys: list[str], table_name: str, condition: str = None) -> dict: - if condition is None: - self._cursor.execute(f"SELECT {', '.join(keys)} FROM {table_name}") - else: - self._cursor.execute( - f"SELECT {', '.join(keys)} FROM {table_name} WHERE {condition}" - ) - return dict(zip(keys, self._cursor.fetchone())) - - def _update(self, table_name: str, db_data: dict): - _id = db_data.get("id") - if _id is None: - raise ValueError("No _id in db_data.") - set_sql = ", ".join([f"{key} = :{key}" for key in db_data.keys()]) - self._cursor.execute( - f"UPDATE {table_name} SET {set_sql} WHERE id = {_id}", db_data - ) - self._conn.commit() - return self._cursor.rowcount == 1 - - def _update_list(self, table_name: str, data_list: list[dict]): - if len(data_list) == 0: - return - set_sql = ", ".join( - [f"{key} = :{key}" for key in data_list[0].keys() if key != "id"] - ) - self._cursor.executemany( - f"UPDATE {table_name} SET {set_sql} WHERE id = :id", data_list - ) - self._conn.commit() - - def _update_section(self, table_name: str, location: dict, update_dict: dict): - set_sql = ", ".join([f"{key} = :{key}" for key in update_dict.keys()]) - sql_loc = f"{location['key']} = {location['value']}" - self._cursor.execute( - f"UPDATE {table_name} SET {set_sql} WHERE {sql_loc}", update_dict - ) - self._conn.commit() - - def _delete_all(self, table_name: str): - self._cursor.execute(f"DELETE FROM {table_name}") - self._conn.commit() - - def _delete(self, table_name: str, condition: dict): - condition_sql = " AND ".join([f"{key} = :{key}" for key in condition.keys()]) - self._cursor.execute( - f"DELETE FROM {table_name} WHERE {condition_sql}", condition - ) - self._conn.commit() - - def _search( - self, table_name: str, keys: list[str] | None = None, condition: dict = None - ): - if keys is None: - select_sql = "*" - else: - select_sql = ", ".join(keys) - if condition is None: - self._cursor.execute(f"SELECT {select_sql} FROM {table_name}") - else: - custom_condition = condition.pop("_custom_condition", None) - condition_sql = " AND ".join( - [f"{key} = :{key}" for key in condition.keys()] - ) + (f" AND {custom_condition}" if custom_condition else "") - self._cursor.execute( - f"SELECT {select_sql} FROM {table_name} WHERE {condition_sql}", - condition, - ) - - def _search_data( - self, table_name: str, keys: list[str] | None = None, condition: dict = None - ) -> dict: - if keys is None: - keys = self.__get_table_columns(table_name) - self._search(table_name, keys, condition) - return dict(zip(keys, self._cursor.fetchone())) - - def _search_datas( - self, table_name: str, keys: list[str] | None = None, condition: dict = None - ) -> list[dict]: - if keys is None: - keys = self.__get_table_columns(table_name) - self._search(table_name, keys, condition) - return [dict(zip(keys, row)) for row in self._cursor.fetchall()] - - def _table_exists(self, table_name: str) -> bool: - self._cursor.execute( - f"SELECT name FROM sqlite_master WHERE type='table' AND name=?;", - (table_name,), - ) - return len(self._cursor.fetchall()) == 1 - - def __get_table_columns(self, table_name: str) -> list[str]: - self._cursor.execute(f"PRAGMA table_info({table_name})") - return [column_info[1] for column_info in self._cursor.fetchall()] - - @staticmethod - def __python_to_sqlite_type(value) -> str: - if isinstance(value, int): - return "INTEGER NOT NULL" - elif isinstance(value, float): - return "REAL NOT NULL" - elif isinstance(value, str): - return "TEXT NOT NULL" - elif isinstance(value, bool): - return "INTEGER NOT NULL" - elif isinstance(value, list): - return "TEXT NOT NULL" - elif value is None: - return "TEXT" - else: - raise ValueError(f"Unsupported data type: {type(value)}") - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self._conn.close() diff --git a/backend/src/module/database/engine.py b/backend/src/module/database/engine.py new file mode 100644 index 00000000..94fa37b0 --- /dev/null +++ b/backend/src/module/database/engine.py @@ -0,0 +1,7 @@ +from sqlmodel import create_engine, Session +from module.conf import DATA_PATH + + +engine = create_engine(DATA_PATH) + +db_session = Session(engine) diff --git a/backend/src/module/database/rss.py b/backend/src/module/database/rss.py new file mode 100644 index 00000000..cfc229b2 --- /dev/null +++ b/backend/src/module/database/rss.py @@ -0,0 +1,97 @@ +import logging + +from sqlmodel import Session, select, delete, and_ + +from module.models import RSSItem, RSSUpdate + +logger = logging.getLogger(__name__) + + +class RSSDatabase: + def __init__(self, session: Session): + self.session = session + + def add(self, data: RSSItem): + # Check if exists + statement = select(RSSItem).where(RSSItem.url == data.url) + db_data = self.session.exec(statement).first() + if db_data: + logger.debug(f"RSS Item {data.url} already exists.") + return False + else: + logger.debug(f"RSS Item {data.url} not exists, adding...") + self.session.add(data) + self.session.commit() + self.session.refresh(data) + return True + + def add_all(self, data: list[RSSItem]): + for item in data: + self.add(item) + + def update(self, _id: int, data: RSSUpdate): + # Check if exists + statement = select(RSSItem).where(RSSItem.id == _id) + db_data = self.session.exec(statement).first() + if not db_data: + return False + # Update + dict_data = data.dict(exclude_unset=True) + for key, value in dict_data.items(): + setattr(db_data, key, value) + self.session.add(db_data) + self.session.commit() + self.session.refresh(db_data) + return True + + def enable(self, _id: int): + statement = select(RSSItem).where(RSSItem.id == _id) + db_data = self.session.exec(statement).first() + if not db_data: + return False + db_data.enabled = True + self.session.add(db_data) + self.session.commit() + self.session.refresh(db_data) + return True + + def disable(self, _id: int): + statement = select(RSSItem).where(RSSItem.id == _id) + db_data = self.session.exec(statement).first() + if not db_data: + return False + db_data.enabled = False + self.session.add(db_data) + self.session.commit() + self.session.refresh(db_data) + return True + + + def search_id(self, _id: int) -> RSSItem: + return self.session.get(RSSItem, _id) + + def search_all(self) -> list[RSSItem]: + return self.session.exec(select(RSSItem)).all() + + def search_active(self) -> list[RSSItem]: + return self.session.exec(select(RSSItem).where(RSSItem.enabled)).all() + + def search_aggregate(self) -> list[RSSItem]: + return self.session.exec( + select(RSSItem).where(and_(RSSItem.aggregate, RSSItem.enabled)) + ).all() + + def delete(self, _id: int) -> bool: + condition = delete(RSSItem).where(RSSItem.id == _id) + try: + self.session.exec(condition) + self.session.commit() + return True + except Exception as e: + logger.error("Delete RSS Item failed.") + return False + + def delete_all(self): + condition = delete(RSSItem) + self.session.exec(condition) + self.session.commit() diff --git a/backend/src/module/database/torrent.py b/backend/src/module/database/torrent.py index bbdf0f8c..c35dbadd 100644 --- a/backend/src/module/database/torrent.py +++ b/backend/src/module/database/torrent.py @@ -1,47 +1,57 @@ import logging -from .connector import DataConnector +from sqlmodel import Session, select + +from module.models import Torrent logger = logging.getLogger(__name__) -class TorrentDatabase(DataConnector): - def update_table(self): - table_name = "torrent" - db_data = self.__data_to_db() - self._update_table(table_name, db_data) +class TorrentDatabase: + def __init__(self, session: Session): + self.session = session - def __data_to_db(self, data: SaveTorrent): - db_data = data.dict() - for key, value in db_data.items(): - if isinstance(value, bool): - db_data[key] = int(value) - elif isinstance(value, list): - db_data[key] = ",".join(value) - return db_data + def add(self, data: Torrent): + self.session.add(data) + self.session.commit() + self.session.refresh(data) + logger.debug(f"Insert {data.name} in database.") - def __db_to_data(self, db_data: dict): - for key, item in db_data.items(): - if isinstance(item, int): - if key not in ["id", "offset", "season", "year"]: - db_data[key] = bool(item) - elif key in ["filter", "rss_link"]: - db_data[key] = item.split(",") - return SaveTorrent(**db_data) + def add_all(self, datas: list[Torrent]): + self.session.add_all(datas) + self.session.commit() + logger.debug(f"Insert {len(datas)} torrents in database.") - def if_downloaded(self, torrent_url: str, torrent_name: str) -> bool: - self._cursor.execute( - "SELECT * FROM torrent WHERE torrent_url = ? OR torrent_name = ?", - (torrent_url, torrent_name), - ) - return bool(self._cursor.fetchone()) + def update(self, data: Torrent): + self.session.add(data) + self.session.commit() + self.session.refresh(data) + logger.debug(f"Update {data.name} in database.") - def insert(self, data: SaveTorrent): - db_data = self.__data_to_db(data) - columns = ", ".join(db_data.keys()) - values = ", ".join([f":{key}" for key in db_data.keys()]) - self._cursor.execute( - f"INSERT INTO torrent ({columns}) VALUES ({values})", db_data - ) - logger.debug(f"Add {data.torrent_name} into database.") - self._conn.commit() + def update_all(self, datas: list[Torrent]): + self.session.add_all(datas) + self.session.commit() + + def update_one_user(self, data: Torrent): + self.session.add(data) + self.session.commit() + self.session.refresh(data) + logger.debug(f"Update {data.name} in database.") + + def search(self, _id: int) -> Torrent: + return self.session.exec(select(Torrent).where(Torrent.id == _id)).first() + + def search_all(self) -> list[Torrent]: + return self.session.exec(select(Torrent)).all() + + def search_rss(self, rss_id: int) -> list[Torrent]: + return self.session.exec(select(Torrent).where(Torrent.rss_id == rss_id)).all() + + def check_new(self, torrents_list: list[Torrent]) -> list[Torrent]: + new_torrents = [] + old_torrents = self.search_all() + old_urls = [t.url for t in old_torrents] + for torrent in torrents_list: + if torrent.url not in old_urls: + new_torrents.append(torrent) + return new_torrents diff --git a/backend/src/module/database/user.py b/backend/src/module/database/user.py index 76dcade4..fdfa6464 100644 --- a/backend/src/module/database/user.py +++ b/backend/src/module/database/user.py @@ -2,73 +2,101 @@ import logging from fastapi import HTTPException -from module.database.connector import DataConnector - +from module.models.user import User, UserUpdate, UserLogin +from module.models import ResponseModel from module.security.jwt import get_password_hash, verify_password -from module.models.user import User +from sqlmodel import Session, select logger = logging.getLogger(__name__) -class AuthDB(DataConnector): - def __init__(self): - super().__init__() - self.__table_name = "user" - if not self._table_exists(self.__table_name): - self.__update_table() - - def __update_table(self): - db_data = self.__data_to_db(User()) - self._update_table(self.__table_name, db_data) - self._insert(self.__table_name, db_data) - - @staticmethod - def __data_to_db(data: User) -> dict: - db_data = data.dict() - db_data["password"] = get_password_hash(db_data["password"]) - return db_data - - @staticmethod - def __db_to_data(db_data: dict) -> User: - return User(**db_data) +class UserDatabase: + def __init__(self, session: Session): + self.session = session def get_user(self, username): - self._cursor.execute( - f"SELECT * FROM {self.__table_name} WHERE username=?", (username,) - ) - result = self._cursor.fetchone() + statement = select(User).where(User.username == username) + result = self.session.exec(statement).first() if not result: - return None - db_data = dict(zip([x[0] for x in self._cursor.description], result)) - return self.__db_to_data(db_data) + raise HTTPException(status_code=404, detail="User not found") + return result - def auth_user(self, username, password) -> bool: - self._cursor.execute( - f"SELECT username, password FROM {self.__table_name} WHERE username=?", - (username,), - ) - result = self._cursor.fetchone() + def auth_user(self, user: User): + statement = select(User).where(User.username == user.username) + result = self.session.exec(statement).first() if not result: - raise HTTPException(status_code=401, detail="User not found") - if not verify_password(password, result[1]): - raise HTTPException(status_code=401, detail="Password error") - return True + return ResponseModel( + status_code=401, + status=False, + msg_en="User not found", + msg_zh="用户不存在" + ) + if not verify_password(user.password, result.password): + return ResponseModel( + status_code=401, + status=False, + msg_en="Incorrect password", + msg_zh="密码错误" + ) + return ResponseModel( + status_code=200, + status=True, + msg_en="Login successfully", + msg_zh="登录成功" + ) - def update_user(self, username, update_user: User): + def update_user(self, username, update_user: UserUpdate): # Update username and password - new_username = update_user.username - new_password = update_user.password - self._cursor.execute( - f""" - UPDATE {self.__table_name} - SET username = '{new_username}', password = '{get_password_hash(new_password)}' - WHERE username = '{username}' + statement = select(User).where(User.username == username) + result = self.session.exec(statement).first() + if not result: + raise HTTPException(status_code=404, detail="User not found") + if update_user.username: + result.username = update_user.username + if update_user.password: + result.password = get_password_hash(update_user.password) + self.session.add(result) + self.session.commit() + return result + + def merge_old_user(self): + # get old data + statement = """ + SELECT * FROM user """ + result = self.session.exec(statement).first() + if not result: + return + # add new data + user = User(username=result.username, password=result.password) + # Drop old table + statement = """ + DROP TABLE user + """ + self.session.exec(statement) + # Create new table + statement = """ + CREATE TABLE user ( + id INTEGER NOT NULL PRIMARY KEY, + username VARCHAR NOT NULL, + password VARCHAR NOT NULL ) - self._conn.commit() + """ + self.session.exec(statement) + self.session.add(user) + self.session.commit() - -if __name__ == "__main__": - with AuthDB() as db: - # db.update_user(UserLogin(username="admin", password="adminadmin"), User(username="admin", password="cica1234")) - db.update_user("admin", User(username="estrella", password="cica1234")) + def add_default_user(self): + # Check if user exists + statement = select(User) + try: + result = self.session.exec(statement).all() + except Exception as e: + self.merge_old_user() + result = self.session.exec(statement).all() + if len(result) != 0: + return + # Add default user + user = User(username="admin", password=get_password_hash("adminadmin")) + self.session.add(user) + self.session.commit() diff --git a/backend/src/module/downloader/client/aria2_downloader.py b/backend/src/module/downloader/client/aria2_downloader.py index 8cfb5aea..2aa1788a 100644 --- a/backend/src/module/downloader/client/aria2_downloader.py +++ b/backend/src/module/downloader/client/aria2_downloader.py @@ -1,13 +1,10 @@ import logging import time -from aria2p import Client, ClientException, API - +from aria2p import API, Client, ClientException from module.conf import settings -from module.downloader.exceptions import ConflictError - logger = logging.getLogger(__name__) diff --git a/backend/src/module/downloader/client/qb_downloader.py b/backend/src/module/downloader/client/qb_downloader.py index 5ddedec2..fe6805f5 100644 --- a/backend/src/module/downloader/client/qb_downloader.py +++ b/backend/src/module/downloader/client/qb_downloader.py @@ -3,9 +3,9 @@ import time from qbittorrentapi import Client, LoginFailed from qbittorrentapi.exceptions import ( + APIConnectionError, Conflict409Error, Forbidden403Error, - APIConnectionError, ) from module.ab_decorator import qb_connect_failed_wait @@ -39,12 +39,12 @@ class QbDownloader: time.sleep(5) times += 1 except Forbidden403Error: - logger.error(f"Login refused by qBittorrent Server") - logger.info(f"Please release the IP in qBittorrent Server") + logger.error("Login refused by qBittorrent Server") + logger.info("Please release the IP in qBittorrent Server") break except APIConnectionError: - logger.error(f"Cannot connect to qBittorrent Server") - logger.info(f"Please check the IP and port in WebUI settings") + logger.error("Cannot connect to qBittorrent Server") + logger.info("Please check the IP and port in WebUI settings") time.sleep(10) times += 1 except Exception as e: @@ -82,10 +82,10 @@ class QbDownloader: status_filter=status_filter, category=category, tag=tag ) - def torrents_add(self, urls, save_path, category, torrent_files=None): + def add_torrents(self, torrent_urls, torrent_files, save_path, category): resp = self._client.torrents_add( is_paused=False, - urls=urls, + urls=torrent_urls, torrent_files=torrent_files, save_path=save_path, category=category, diff --git a/backend/src/module/downloader/download_client.py b/backend/src/module/downloader/download_client.py index 6b003e1e..d01d4fa3 100644 --- a/backend/src/module/downloader/download_client.py +++ b/backend/src/module/downloader/download_client.py @@ -1,11 +1,11 @@ import logging -import re + +from module.conf import settings +from module.models import Bangumi, Torrent +from module.network import RequestContent from .path import TorrentPath -from module.models import BangumiData -from module.conf import settings - logger = logging.getLogger(__name__) @@ -56,25 +56,25 @@ class DownloadClient(TorrentPath): def init_downloader(self): prefs = { "rss_auto_downloading_enabled": True, - "rss_max_articles_per_feed": 5000, + "rss_max_articles_per_feed": 500, "rss_processing_enabled": True, + "rss_refresh_interval": 30, } self.client.prefs_init(prefs=prefs) try: self.client.add_category("BangumiCollection") - except Exception as e: + except Exception: logger.debug("[Downloader] Cannot add new category, maybe already exists.") if settings.downloader.path == "": prefs = self.client.get_app_prefs() settings.downloader.path = self._join_path(prefs["save_path"], "Bangumi") - def set_rule(self, data: BangumiData): + def set_rule(self, data: Bangumi): data.rule_name = self._rule_name(data) data.save_path = self._gen_save_path(data) - raw_title = re.escape(data.title_raw) rule = { "enable": True, - "mustContain": raw_title, + "mustContain": data.title_raw, "mustNotContain": "|".join(data.filter), "useRegex": True, "episodeFilter": "", @@ -93,7 +93,7 @@ class DownloadClient(TorrentPath): f"[Downloader] Add {data.official_title} Season {data.season} to auto download rules." ) - def set_rules(self, bangumi_info: list[BangumiData]): + def set_rules(self, bangumi_info: list[Bangumi]): logger.debug("[Downloader] Start adding rules.") for info in bangumi_info: self.set_rule(info) @@ -112,19 +112,39 @@ class DownloadClient(TorrentPath): def delete_torrent(self, hashes): self.client.torrents_delete(hashes) - logger.info(f"[Downloader] Remove torrents.") + logger.info("[Downloader] Remove torrents.") - def add_torrent(self, torrent: dict): - if self.client.torrents_add( - urls=torrent.get("urls"), - torrent_files=torrent.get("torrent_files"), - save_path=torrent.get("save_path"), + def add_torrent(self, torrent: Torrent | list, bangumi: Bangumi) -> bool: + if not bangumi.save_path: + bangumi.save_path = self._gen_save_path(bangumi) + with RequestContent() as req: + if isinstance(torrent, list): + if len(torrent) == 0: + logger.debug(f"[Downloader] No torrent found: {bangumi.official_title}") + return False + if "magnet" in torrent[0].url: + torrent_url = [t.url for t in torrent] + torrent_file = None + else: + torrent_file = [req.get_content(t.url) for t in torrent] + torrent_url = None + else: + if "magnet" in torrent.url: + torrent_url = torrent.url + torrent_file = None + else: + torrent_file = req.get_content(torrent.url) + torrent_url = None + if self.client.add_torrents( + torrent_urls=torrent_url, + torrent_files=torrent_file, + save_path=bangumi.save_path, category="Bangumi", ): - logger.debug(f"[Downloader] Add torrent: {torrent.get('save_path')}") + logger.debug(f"[Downloader] Add torrent: {bangumi.official_title}") return True else: - logger.error(f"[Downloader] Add torrent failed: {torrent.get('save_path')}") + logger.debug(f"[Downloader] Torrent added before: {bangumi.official_title}") return False def move_torrent(self, hashes, location): diff --git a/backend/src/module/downloader/path.py b/backend/src/module/downloader/path.py index e0ed8043..86d2e8e2 100644 --- a/backend/src/module/downloader/path.py +++ b/backend/src/module/downloader/path.py @@ -1,13 +1,10 @@ -import re import logging +from os import PathLike +import re +from pathlib import Path from module.conf import settings -from module.models import BangumiData - -if ":\\" in settings.downloader.path: - import ntpath as path -else: - import os.path as path +from module.models import Bangumi, BangumiUpdate logger = logging.getLogger(__name__) @@ -22,7 +19,7 @@ class TorrentPath: subtitle_list = [] for f in info.files: file_name = f.name - suffix = path.splitext(file_name)[-1] + suffix = Path(file_name).suffix if suffix.lower() in [".mp4", ".mkv"]: media_list.append(file_name) elif suffix.lower() in [".ass", ".srt"]: @@ -30,10 +27,10 @@ class TorrentPath: return media_list, subtitle_list @staticmethod - def _path_to_bangumi(save_path): + def _path_to_bangumi(save_path: PathLike[str] | str): # Split save path and download path - save_parts = save_path.split(path.sep) - download_parts = settings.downloader.path.split(path.sep) + save_parts = Path(save_path).parts + download_parts = Path(settings.downloader.path).parts # Get bangumi name and season bangumi_name = "" season = 1 @@ -45,22 +42,22 @@ class TorrentPath: return bangumi_name, season @staticmethod - def _file_depth(file_path): - return len(file_path.split(path.sep)) + def _file_depth(file_path: PathLike[str] | str): + return len(Path(file_path).parts) - def is_ep(self, file_path): + def is_ep(self, file_path: PathLike[str] | str): return self._file_depth(file_path) <= 2 @staticmethod - def _gen_save_path(data: BangumiData): + def _gen_save_path(data: Bangumi | BangumiUpdate): folder = ( f"{data.official_title} ({data.year})" if data.year else data.official_title ) - save_path = path.join(settings.downloader.path, folder, f"Season {data.season}") - return save_path + save_path = Path(settings.downloader.path) / folder / f"Season {data.season}" + return str(save_path) @staticmethod - def _rule_name(data: BangumiData): + def _rule_name(data: Bangumi): rule_name = ( f"[{data.group_name}] {data.official_title} S{data.season}" if settings.bangumi_manage.group_tag @@ -70,4 +67,4 @@ class TorrentPath: @staticmethod def _join_path(*args): - return path.join(*args) + return str(Path(*args)) diff --git a/backend/src/module/manager/collector.py b/backend/src/module/manager/collector.py index 86524221..f6f1dab8 100644 --- a/backend/src/module/manager/collector.py +++ b/backend/src/module/manager/collector.py @@ -1,58 +1,58 @@ import logging -from fastapi.responses import JSONResponse - from module.downloader import DownloadClient -from module.models import BangumiData -from module.database import BangumiDatabase +from module.models import Bangumi, ResponseModel from module.searcher import SearchTorrent +from module.rss import RSSEngine logger = logging.getLogger(__name__) class SeasonCollector(DownloadClient): - def add_season_torrents(self, data: BangumiData, torrents, torrent_files=None): - if torrent_files: - download_info = { - "torrent_files": torrent_files, - "save_path": self._gen_save_path(data), - } - return self.add_torrent(download_info) - else: - download_info = { - "urls": [torrent.torrent_link for torrent in torrents], - "save_path": self._gen_save_path(data), - } - return self.add_torrent(download_info) - - def collect_season(self, data: BangumiData, link: str = None, proxy: bool = False): - logger.info(f"Start collecting {data.official_title} Season {data.season}...") + def collect_season(self, bangumi: Bangumi, link: str = None): + logger.info( + f"Start collecting {bangumi.official_title} Season {bangumi.season}..." + ) with SearchTorrent() as st: if not link: - torrents = st.search_season(data) + torrents = st.search_season(bangumi) else: - torrents = st.get_torrents(link, _filter="|".join(data.filter)) - torrent_files = None - if proxy: - torrent_files = [ - st.get_content(torrent.torrent_link) for torrent in torrents - ] - return self.add_season_torrents( - data=data, torrents=torrents, torrent_files=torrent_files - ) + torrents = st.get_torrents(link, bangumi.filter.replace(",", "|")) + if self.add_torrent(torrents, bangumi): + logger.info(f"Collections of {bangumi.official_title} Season {bangumi.season} completed.") + bangumi.eps_collect = True + with RSSEngine() as engine: + engine.bangumi.update(bangumi) + return ResponseModel( + status=True, + status_code=200, + msg_en=f"Collections of {bangumi.official_title} Season {bangumi.season} completed.", + msg_zh=f"收集 {bangumi.official_title} 第 {bangumi.season} 季完成。", + ) + else: + logger.warning(f"Collection of {bangumi.official_title} Season {bangumi.season} failed.") + return ResponseModel( + status=False, + status_code=406, + msg_en=f"Collection of {bangumi.official_title} Season {bangumi.season} failed.", + msg_zh=f"收集 {bangumi.official_title} 第 {bangumi.season} 季失败。", + ) - def subscribe_season(self, data: BangumiData): - with BangumiDatabase() as db: + @staticmethod + def subscribe_season(data: Bangumi): + with RSSEngine() as engine: data.added = True data.eps_collect = True - self.set_rule(data) - db.insert(data) - self.add_rss_feed(data.rss_link[0], item_path=data.official_title) + engine.add_rss( + rss_link=data.rss_link, name=data.official_title, aggregate=False + ) + engine.bangumi.add(data) + return engine.download_bangumi(data) def eps_complete(): - with BangumiDatabase() as bd: - datas = bd.not_complete() + with RSSEngine() as engine: + datas = engine.bangumi.not_complete() if datas: logger.info("Start collecting full season...") for data in datas: @@ -60,4 +60,4 @@ def eps_complete(): with SeasonCollector() as sc: sc.collect_season(data) data.eps_collect = True - bd.update_list(datas) + engine.bangumi.update_all(datas) diff --git a/backend/src/module/manager/renamer.py b/backend/src/module/manager/renamer.py index 9b04d145..940cdef9 100644 --- a/backend/src/module/manager/renamer.py +++ b/backend/src/module/manager/renamer.py @@ -1,11 +1,9 @@ import logging -from module.downloader import DownloadClient - -from module.parser import TitleParser -from module.models import SubtitleFile, EpisodeFile, Notification from module.conf import settings - +from module.downloader import DownloadClient +from module.models import EpisodeFile, Notification, SubtitleFile +from module.parser import TitleParser logger = logging.getLogger(__name__) diff --git a/backend/src/module/manager/torrent.py b/backend/src/module/manager/torrent.py index a11bb899..9a559fbc 100644 --- a/backend/src/module/manager/torrent.py +++ b/backend/src/module/manager/torrent.py @@ -1,138 +1,154 @@ import logging + from fastapi.responses import JSONResponse +from module.database import Database from module.downloader import DownloadClient -from module.models import BangumiData -from module.database import BangumiDatabase - +from module.models import Bangumi, BangumiUpdate, ResponseModel logger = logging.getLogger(__name__) -class TorrentManager(BangumiDatabase): +class TorrentManager(Database): @staticmethod - def __match_torrents_list(data: BangumiData) -> list: + def __match_torrents_list(data: Bangumi | BangumiUpdate) -> list: with DownloadClient() as client: torrents = client.get_torrent_info(status_filter=None) return [ torrent.hash for torrent in torrents if torrent.save_path == data.save_path ] - def delete_torrents(self, data: BangumiData, client: DownloadClient): + def delete_torrents(self, data: Bangumi, client: DownloadClient): hash_list = self.__match_torrents_list(data) if hash_list: client.delete_torrent(hash_list) logger.info(f"Delete rule and torrents for {data.official_title}") - return f"Delete {data.official_title} torrents." + return ResponseModel( + status_code=200, + status=True, + msg_en=f"Delete rule and torrents for {data.official_title}", + msg_zh=f"删除 {data.official_title} 规则和种子", + ) else: - return f"Can't find {data.official_title} torrents." + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find torrents for {data.official_title}", + msg_zh=f"无法找到 {data.official_title} 的种子", + ) def delete_rule(self, _id: int | str, file: bool = False): - data = self.search_id(int(_id)) - if isinstance(data, BangumiData): + data = self.bangumi.search_id(int(_id)) + if isinstance(data, Bangumi): with DownloadClient() as client: - client.remove_rule(data.rule_name) - client.remove_rss_feed(data.official_title) - self.delete_one(int(_id)) + # client.remove_rule(data.rule_name) + # client.remove_rss_feed(data.official_title) + self.rss.delete(data.official_title) + self.bangumi.delete_one(int(_id)) if file: torrent_message = self.delete_torrents(data, client) - return JSONResponse( - status_code=200, - content={ - "msg": f"Delete {data.official_title} rule. {torrent_message}" - }, - ) + return torrent_message logger.info(f"[Manager] Delete rule for {data.official_title}") - return JSONResponse( + return ResponseModel( status_code=200, - content={"msg": f"Delete rule for {data.official_title}"}, + status=True, + msg_en=f"Delete rule for {data.official_title}", + msg_zh=f"删除 {data.official_title} 规则", ) else: - return JSONResponse( - status_code=406, content={"msg": f"Can't find id {_id}"} + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find id {_id}", + msg_zh=f"无法找到 id {_id}", ) def disable_rule(self, _id: str | int, file: bool = False): - data = self.search_id(int(_id)) - if isinstance(data, BangumiData): + data = self.bangumi.search_id(int(_id)) + if isinstance(data, Bangumi): with DownloadClient() as client: - client.remove_rule(data.rule_name) + # client.remove_rule(data.rule_name) data.deleted = True - self.update_one(data) + self.bangumi.update(data) if file: torrent_message = self.delete_torrents(data, client) - return JSONResponse( - status_code=200, - content={ - "msg": f"Disable {data.official_title} rule. {torrent_message}" - }, - ) + return torrent_message logger.info(f"[Manager] Disable rule for {data.official_title}") - return JSONResponse( + return ResponseModel( status_code=200, - content={ - "msg": f"Disable {data.official_title} rule.", - }, + status=True, + msg_en=f"Disable rule for {data.official_title}", + msg_zh=f"禁用 {data.official_title} 规则", ) else: - return JSONResponse( - status_code=406, content={"msg": f"Can't find id {_id}"} + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find id {_id}", + msg_zh=f"无法找到 id {_id}", ) def enable_rule(self, _id: str | int): - data = self.search_id(int(_id)) - if isinstance(data, BangumiData): + data = self.bangumi.search_id(int(_id)) + if data: data.deleted = False - self.update_one(data) - with DownloadClient() as client: - client.set_rule(data) + self.bangumi.update(data) logger.info(f"[Manager] Enable rule for {data.official_title}") - return JSONResponse( + return ResponseModel( status_code=200, - content={ - "msg": f"Enable {data.official_title} rule.", - }, + status=True, + msg_en=f"Enable rule for {data.official_title}", + msg_zh=f"启用 {data.official_title} 规则", ) else: - return JSONResponse( - status_code=406, content={"msg": f"Can't find bangumi id {_id}"} + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find id {_id}", + msg_zh=f"无法找到 id {_id}", ) - def update_rule(self, data: BangumiData): - old_data = self.search_id(data.id) - if not old_data: - logger.error(f"[Manager] Can't find data with {data.id}") - return JSONResponse( - status_code=406, content={"msg": f"Can't find data with {data.id}"} - ) - else: + def update_rule(self, bangumi_id, data: BangumiUpdate): + old_data: Bangumi = self.bangumi.search_id(bangumi_id) + if old_data: # Move torrent - match_list = self.__match_torrents_list(data) + match_list = self.__match_torrents_list(old_data) with DownloadClient() as client: path = client._gen_save_path(data) if match_list: client.move_torrent(match_list, path) - # Set new download rule - client.remove_rule(data.rule_name) - client.set_rule(data) - self.update_one(data) - return JSONResponse( + self.bangumi.update(data, bangumi_id) + return ResponseModel( status_code=200, - content={ - "msg": f"Set new path for {data.official_title}", - }, + status=True, + msg_en=f"Update rule for {data.official_title}", + msg_zh=f"更新 {data.official_title} 规则", + ) + else: + logger.error(f"[Manager] Can't find data with {bangumi_id}") + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find data with {bangumi_id}", + msg_zh=f"无法找到 id {bangumi_id} 的数据", ) + def search_all_bangumi(self): - datas = self.search_all() + datas = self.bangumi.search_all() if not datas: return [] return [data for data in datas if not data.deleted] def search_one(self, _id: int | str): - data = self.search_id(int(_id)) + data = self.bangumi.search_id(int(_id)) if not data: logger.error(f"[Manager] Can't find data with {_id}") - return {"status": "error", "msg": f"Can't find data with {_id}"} + return ResponseModel( + status_code=406, + status=False, + msg_en=f"Can't find data with {_id}", + msg_zh=f"无法找到 id {_id} 的数据", + ) else: return data diff --git a/backend/src/module/models/__init__.py b/backend/src/module/models/__init__.py index 508d68f1..7a00b90d 100644 --- a/backend/src/module/models/__init__.py +++ b/backend/src/module/models/__init__.py @@ -1,5 +1,6 @@ -from .bangumi import * +from .bangumi import Bangumi, Episode, BangumiUpdate, Notification from .config import Config -from .torrent import EpisodeFile, SubtitleFile -from .user import UserLogin -from .torrent import TorrentBase +from .rss import RSSItem, RSSUpdate +from .torrent import EpisodeFile, SubtitleFile, Torrent, TorrentUpdate +from .user import UserLogin, User, UserUpdate +from .response import ResponseModel, APIResponse diff --git a/backend/src/module/models/bangumi.py b/backend/src/module/models/bangumi.py index 2dd73340..82ee9747 100644 --- a/backend/src/module/models/bangumi.py +++ b/backend/src/module/models/bangumi.py @@ -1,26 +1,54 @@ -from pydantic import BaseModel, Field from dataclasses import dataclass +from pydantic import BaseModel +from sqlmodel import SQLModel, Field +from typing import Optional -class BangumiData(BaseModel): - id: int = Field(0, alias="id", title="番剧ID") - official_title: str = Field("official_title", alias="official_title", title="番剧中文名") - year: str | None = Field(None, alias="year", title="番剧年份") - title_raw: str = Field("title_raw", alias="title_raw", title="番剧原名") - season: int = Field(1, alias="season", title="番剧季度") - season_raw: str | None = Field(None, alias="season_raw", title="番剧季度原名") - group_name: str | None = Field(None, alias="group_name", title="字幕组") - dpi: str | None = Field(None, alias="dpi", title="分辨率") - source: str | None = Field(None, alias="source", title="来源") - subtitle: str | None = Field(None, alias="subtitle", title="字幕") - eps_collect: bool = Field(False, alias="eps_collect", title="是否已收集") - offset: int = Field(0, alias="offset", title="番剧偏移量") - filter: list[str] = Field(["720", "\\d+-\\d+"], alias="filter", title="番剧过滤器") - rss_link: list[str] = Field([], alias="rss_link", title="番剧RSS链接") - poster_link: str | None = Field(None, alias="poster_link", title="番剧海报链接") - added: bool = Field(False, alias="added", title="是否已添加") - rule_name: str | None = Field(None, alias="rule_name", title="番剧规则名") - save_path: str | None = Field(None, alias="save_path", title="番剧保存路径") + +class Bangumi(SQLModel, table=True): + id: int = Field(default=None, primary_key=True) + official_title: str = Field( + default="official_title", alias="official_title", title="番剧中文名" + ) + year: Optional[str] = Field(alias="year", title="番剧年份") + title_raw: str = Field(default="title_raw", alias="title_raw", title="番剧原名") + season: int = Field(default=1, alias="season", title="番剧季度") + season_raw: Optional[str] = Field(alias="season_raw", title="番剧季度原名") + group_name: Optional[str] = Field(alias="group_name", title="字幕组") + dpi: Optional[str] = Field(alias="dpi", title="分辨率") + source: Optional[str] = Field(alias="source", title="来源") + subtitle: Optional[str] = Field(alias="subtitle", title="字幕") + eps_collect: bool = Field(default=False, alias="eps_collect", title="是否已收集") + offset: int = Field(default=0, alias="offset", title="番剧偏移量") + filter: str = Field(default="720,\\d+-\\d+", alias="filter", title="番剧过滤器") + rss_link: str = Field(default="", alias="rss_link", title="番剧RSS链接") + poster_link: Optional[str] = Field(alias="poster_link", title="番剧海报链接") + added: bool = Field(default=False, alias="added", title="是否已添加") + rule_name: Optional[str] = Field(alias="rule_name", title="番剧规则名") + save_path: Optional[str] = Field(alias="save_path", title="番剧保存路径") + deleted: bool = Field(False, alias="deleted", title="是否已删除") + + +class BangumiUpdate(SQLModel): + official_title: str = Field( + default="official_title", alias="official_title", title="番剧中文名" + ) + year: Optional[str] = Field(alias="year", title="番剧年份") + title_raw: str = Field(default="title_raw", alias="title_raw", title="番剧原名") + season: int = Field(default=1, alias="season", title="番剧季度") + season_raw: Optional[str] = Field(alias="season_raw", title="番剧季度原名") + group_name: Optional[str] = Field(alias="group_name", title="字幕组") + dpi: Optional[str] = Field(alias="dpi", title="分辨率") + source: Optional[str] = Field(alias="source", title="来源") + subtitle: Optional[str] = Field(alias="subtitle", title="字幕") + eps_collect: bool = Field(default=False, alias="eps_collect", title="是否已收集") + offset: int = Field(default=0, alias="offset", title="番剧偏移量") + filter: str = Field(default="720,\\d+-\\d+", alias="filter", title="番剧过滤器") + rss_link: str = Field(default="", alias="rss_link", title="番剧RSS链接") + poster_link: Optional[str] = Field(alias="poster_link", title="番剧海报链接") + added: bool = Field(default=False, alias="added", title="是否已添加") + rule_name: Optional[str] = Field(alias="rule_name", title="番剧规则名") + save_path: Optional[str] = Field(alias="save_path", title="番剧保存路径") deleted: bool = Field(False, alias="deleted", title="是否已删除") @@ -28,14 +56,14 @@ class Notification(BaseModel): official_title: str = Field(..., alias="official_title", title="番剧名") season: int = Field(..., alias="season", title="番剧季度") episode: int = Field(..., alias="episode", title="番剧集数") - poster_path: str | None = Field(None, alias="poster_path", title="番剧海报路径") + poster_path: Optional[str] = Field(None, alias="poster_path", title="番剧海报路径") @dataclass class Episode: - title_en: str | None - title_zh: str | None - title_jp: str | None + title_en: Optional[str] + title_zh: Optional[str] + title_jp: Optional[str] season: int season_raw: str episode: int diff --git a/backend/src/module/models/config.py b/backend/src/module/models/config.py index 6e260c31..df15546a 100644 --- a/backend/src/module/models/config.py +++ b/backend/src/module/models/config.py @@ -1,29 +1,38 @@ +from os.path import expandvars from pydantic import BaseModel, Field -# Sub config - class Program(BaseModel): - rss_time: int = Field(7200, description="Sleep time") + rss_time: int = Field(900, description="Sleep time") rename_time: int = Field(60, description="Rename times in one loop") webui_port: int = Field(7892, description="WebUI port") class Downloader(BaseModel): type: str = Field("qbittorrent", description="Downloader type") - host: str = Field("172.17.0.1:8080", description="Downloader host") - username: str = Field("admin", description="Downloader username") - password: str = Field("adminadmin", description="Downloader password") + host_: str = Field("172.17.0.1:8080", alias="host", description="Downloader host") + username_: str = Field("admin", alias="username", description="Downloader username") + password_: str = Field( + "adminadmin", alias="password", description="Downloader password" + ) path: str = Field("/downloads/Bangumi", description="Downloader path") ssl: bool = Field(False, description="Downloader ssl") + @property + def host(self): + return expandvars(self.host_) + + @property + def username(self): + return expandvars(self.username_) + + @property + def password(self): + return expandvars(self.password_) + class RSSParser(BaseModel): enable: bool = Field(True, description="Enable RSS parser") - type: str = Field("mikan", description="RSS parser type") - token: str = Field("token", description="RSS parser token") - custom_url: str = Field("mikanani.me", description="Custom RSS host url") - parser_type: str = Field("parser", description="Parser type") filter: list[str] = Field(["720", r"\d+-\d"], description="Filter") language: str = "zh" @@ -45,15 +54,31 @@ class Proxy(BaseModel): type: str = Field("http", description="Proxy type") host: str = Field("", description="Proxy host") port: int = Field(0, description="Proxy port") - username: str = Field("", description="Proxy username") - password: str = Field("", description="Proxy password") + username_: str = Field("", alias="username", description="Proxy username") + password_: str = Field("", alias="password", description="Proxy password") + + @property + def username(self): + return expandvars(self.username_) + + @property + def password(self): + return expandvars(self.password_) class Notification(BaseModel): enable: bool = Field(False, description="Enable notification") type: str = Field("telegram", description="Notification type") - token: str = Field("", description="Notification token") - chat_id: str = Field("", description="Notification chat id") + token_: str = Field("", alias="token", description="Notification token") + chat_id_: str = Field("", alias="chat_id", description="Notification chat id") + + @property + def token(self): + return expandvars(self.token_) + + @property + def chat_id(self): + return expandvars(self.chat_id_) class Config(BaseModel): @@ -64,3 +89,6 @@ class Config(BaseModel): log: Log = Log() proxy: Proxy = Proxy() notification: Notification = Notification() + + def dict(self, *args, by_alias=True, **kwargs): + return super().dict(*args, by_alias=by_alias, **kwargs) diff --git a/backend/src/module/models/response.py b/backend/src/module/models/response.py new file mode 100644 index 00000000..9bd35272 --- /dev/null +++ b/backend/src/module/models/response.py @@ -0,0 +1,14 @@ +from pydantic import BaseModel, Field + + +class ResponseModel(BaseModel): + status: bool = Field(..., example=True) + status_code: int = Field(..., example=200) + msg_en: str + msg_zh: str + + +class APIResponse(BaseModel): + status: bool = Field(..., example=True) + msg_en: str = Field(..., example="Success") + msg_zh: str = Field(..., example="成功") \ No newline at end of file diff --git a/backend/src/module/models/rss.py b/backend/src/module/models/rss.py new file mode 100644 index 00000000..7275bb12 --- /dev/null +++ b/backend/src/module/models/rss.py @@ -0,0 +1,19 @@ +from sqlmodel import SQLModel, Field +from typing import Optional + + +class RSSItem(SQLModel, table=True): + id: int = Field(default=None, primary_key=True, alias="id") + name: Optional[str] = Field(None, alias="name") + url: str = Field("https://mikanani.me", alias="url") + aggregate: bool = Field(False, alias="aggregate") + parser: str = Field("mikan", alias="parser") + enabled: bool = Field(True, alias="enabled") + + +class RSSUpdate(SQLModel): + name: Optional[str] = Field(None, alias="name") + url: Optional[str] = Field("https://mikanani.me", alias="url") + aggregate: Optional[bool] = Field(True, alias="aggregate") + parser: Optional[str] = Field("mikan", alias="parser") + enabled: Optional[bool] = Field(True, alias="enabled") diff --git a/backend/src/module/models/torrent.py b/backend/src/module/models/torrent.py index 892d66d6..57e818a3 100644 --- a/backend/src/module/models/torrent.py +++ b/backend/src/module/models/torrent.py @@ -1,16 +1,20 @@ -from pydantic import BaseModel, Field +from pydantic import BaseModel +from sqlmodel import SQLModel, Field +from typing import Optional -class TorrentBase(BaseModel): - name: str = Field(...) - torrent_link: str = Field(...) - homepage: str | None = Field(None) +class Torrent(SQLModel, table=True): + id: int = Field(default=None, primary_key=True, alias="id") + bangumi_id: Optional[int] = Field(None, alias="refer_id", foreign_key="bangumi.id") + rss_id: Optional[int] = Field(None, alias="rss_id", foreign_key="rssitem.id") + name: str = Field("", alias="name") + url: str = Field("https://example.com/torrent", alias="url") + homepage: Optional[str] = Field(None, alias="homepage") + downloaded: bool = Field(False, alias="downloaded") -class FileSet(BaseModel): - media_path: str = Field(...) - sc_subtitle: str | None = Field(None) - tc_subtitle: str | None = Field(None) +class TorrentUpdate(SQLModel): + downloaded: bool = Field(False, alias="downloaded") class EpisodeFile(BaseModel): diff --git a/backend/src/module/models/user.py b/backend/src/module/models/user.py index 36512642..3e5cef29 100644 --- a/backend/src/module/models/user.py +++ b/backend/src/module/models/user.py @@ -1,14 +1,24 @@ -from pydantic import BaseModel, Field +from pydantic import BaseModel +from typing import Optional +from sqlmodel import SQLModel, Field -class User(BaseModel): +class User(SQLModel, table=True): + id: int = Field(default=None, primary_key=True) username: str = Field( "admin", min_length=4, max_length=20, regex=r"^[a-zA-Z0-9_]+$" ) password: str = Field("adminadmin", min_length=8) -class UserLogin(BaseModel): +class UserUpdate(SQLModel): + username: Optional[str] = Field( + None, min_length=4, max_length=20, regex=r"^[a-zA-Z0-9_]+$" + ) + password: Optional[str] = Field(None, min_length=8) + + +class UserLogin(SQLModel): username: str password: str = Field(..., min_length=8) diff --git a/backend/src/module/network/__init__.py b/backend/src/module/network/__init__.py index aca7b27b..e576795a 100644 --- a/backend/src/module/network/__init__.py +++ b/backend/src/module/network/__init__.py @@ -1 +1 @@ -from .request_contents import RequestContent, TorrentInfo +from .request_contents import RequestContent diff --git a/backend/src/module/network/request_contents.py b/backend/src/module/network/request_contents.py index 77c074df..bde907a4 100644 --- a/backend/src/module/network/request_contents.py +++ b/backend/src/module/network/request_contents.py @@ -1,84 +1,52 @@ import re +import logging import xml.etree.ElementTree -from dataclasses import dataclass -from bs4 import BeautifulSoup +from module.conf import settings +from module.models import Torrent from .request_url import RequestURL -from .site import mikan_parser -from module.conf import settings +from .site import rss_parser - -@dataclass -class TorrentInfo: - name: str - torrent_link: str - homepage: str - _poster_link: str | None = None - _official_title: str | None = None - - def __fetch_mikan_info(self): - if self._poster_link is None or self._official_title is None: - with RequestContent() as req: - self._poster_link, self._official_title = req.get_mikan_info( - self.homepage - ) - - @property - def poster_link(self) -> str: - self.__fetch_mikan_info() - return self._poster_link - - @property - def official_title(self) -> str: - self.__fetch_mikan_info() - return self._official_title +logger = logging.getLogger(__name__) class RequestContent(RequestURL): - # Mikanani RSS def get_torrents( self, _url: str, _filter: str = "|".join(settings.rss_parser.filter), + limit: int = 100, retry: int = 3, - ) -> list[TorrentInfo]: - try: - soup = self.get_xml(_url, retry) - torrent_titles, torrent_urls, torrent_homepage = mikan_parser(soup) - torrents: list[TorrentInfo] = [] + ) -> list[Torrent]: + soup = self.get_xml(_url, retry) + if soup: + torrent_titles, torrent_urls, torrent_homepage = rss_parser(soup) + torrents: list[Torrent] = [] for _title, torrent_url, homepage in zip( torrent_titles, torrent_urls, torrent_homepage ): if re.search(_filter, _title) is None: torrents.append( - TorrentInfo( - name=_title, torrent_link=torrent_url, homepage=homepage - ) + Torrent(name=_title, url=torrent_url, homepage=homepage) ) + if len(torrents) >= limit: + break return torrents - except ConnectionError: + else: + logger.warning(f"[Network] Failed to get torrents: {_url}") return [] - def get_mikan_info(self, _url) -> tuple[str, str]: - content = self.get_html(_url) - soup = BeautifulSoup(content, "html.parser") - poster_div = soup.find("div", {"class": "bangumi-poster"}) - poster_style = poster_div.get("style") - official_title = soup.select_one( - 'p.bangumi-title a[href^="/Home/Bangumi/"]' - ).text - if poster_style: - poster_path = poster_style.split("url('")[1].split("')")[0] - return poster_path, official_title - return "", "" - def get_xml(self, _url, retry: int = 3) -> xml.etree.ElementTree.Element: - return xml.etree.ElementTree.fromstring(self.get_url(_url, retry).text) + req = self.get_url(_url, retry) + if req: + return xml.etree.ElementTree.fromstring(req.text) # API JSON def get_json(self, _url) -> dict: - return self.get_url(_url).json() + req = self.get_url(_url) + if req: + return req.json() def post_json(self, _url, data: dict) -> dict: return self.post_url(_url, data).json() @@ -90,7 +58,14 @@ class RequestContent(RequestURL): return self.get_url(_url).text def get_content(self, _url): - return self.get_url(_url).content + req = self.get_url(_url) + if req: + return req.content def check_connection(self, _url): return self.check_url(_url) + + def get_rss_title(self, _url): + soup = self.get_xml(_url) + if soup: + return soup.find("./channel/title").text diff --git a/backend/src/module/network/request_url.py b/backend/src/module/network/request_url.py index f4b65e7d..bee1a8a2 100644 --- a/backend/src/module/network/request_url.py +++ b/backend/src/module/network/request_url.py @@ -1,9 +1,9 @@ +import logging +import socket import time import requests -import socket import socks -import logging from module.conf import settings @@ -35,7 +35,7 @@ class RequestURL: break logger.error(f"[Network] Failed connecting to {url}") logger.warning("[Network] Please check DNS/Connection settings") - raise ConnectionError(f"Failed connecting to {url}") + return None def post_url(self, url: str, data: dict, retry=3): try_time = 0 @@ -59,7 +59,7 @@ class RequestURL: break logger.error(f"[Network] Failed connecting to {url}") logger.warning("[Network] Please check DNS/Connection settings") - raise ConnectionError(f"Failed connecting to {url}") + return None def check_url(self, url: str): if "://" not in url: @@ -68,7 +68,7 @@ class RequestURL: req = requests.head(url=url, headers=self.header, timeout=5) req.raise_for_status() return True - except requests.RequestException as e: + except requests.RequestException: logger.debug(f"[Network] Cannot connect to {url}.") return False diff --git a/backend/src/module/network/site/__init__.py b/backend/src/module/network/site/__init__.py index 70f16f74..adb8e1cc 100644 --- a/backend/src/module/network/site/__init__.py +++ b/backend/src/module/network/site/__init__.py @@ -1 +1 @@ -from .mikan import mikan_parser +from .mikan import rss_parser diff --git a/backend/src/module/network/site/mikan.py b/backend/src/module/network/site/mikan.py index 0ad4314b..00181a87 100644 --- a/backend/src/module/network/site/mikan.py +++ b/backend/src/module/network/site/mikan.py @@ -1,4 +1,4 @@ -def mikan_parser(soup): +def rss_parser(soup): torrent_titles = [] torrent_urls = [] torrent_homepage = [] @@ -7,3 +7,7 @@ def mikan_parser(soup): torrent_urls.append(item.find("enclosure").attrib["url"]) torrent_homepage.append(item.find("link").text) return torrent_titles, torrent_urls, torrent_homepage + + +def mikan_title(soup): + return soup.find("title").text diff --git a/backend/src/module/notification/notification.py b/backend/src/module/notification/notification.py index a4bd7c72..909fc92c 100644 --- a/backend/src/module/notification/notification.py +++ b/backend/src/module/notification/notification.py @@ -1,11 +1,15 @@ import logging -from .plugin import * - -from module.models import Notification from module.conf import settings -from module.database import BangumiDatabase +from module.database import Database +from module.models import Notification +from .plugin import ( + BarkNotification, + ServerChanNotification, + TelegramNotification, + WecomNotification, +) logger = logging.getLogger(__name__) @@ -32,19 +36,9 @@ class PostNotification: @staticmethod def _get_poster(notify: Notification): - with BangumiDatabase() as db: - poster_path = db.match_poster(notify.official_title) - if poster_path: - poster_link = "https://mikanani.me" + poster_path - # text = f""" - # 番剧名称:{notify.official_title}\n季度: 第{notify.season}季\n更新集数: 第{notify.episode}集\n{poster_link}\n - # """ - else: - poster_link = "https://mikanani.me" - # text = f""" - # 番剧名称:{notify.official_title}\n季度: 第{notify.season}季\n更新集数: 第{notify.episode}集\n - # """ - notify.poster_path = poster_link + with Database() as db: + poster_path = db.bangumi.match_poster(notify.official_title) + notify.poster_path = poster_path def send_msg(self, notify: Notification) -> bool: self._get_poster(notify) @@ -61,13 +55,3 @@ class PostNotification: def __exit__(self, exc_type, exc_val, exc_tb): self.notifier.__exit__(exc_type, exc_val, exc_tb) - - -if __name__ == "__main__": - info = Notification( - official_title="久保同学不放过我", - season=2, - episode=1, - ) - with PostNotification() as client: - client.send_msg(info) diff --git a/backend/src/module/notification/plugin/bark.py b/backend/src/module/notification/plugin/bark.py index e825a2c9..1bddf09a 100644 --- a/backend/src/module/notification/plugin/bark.py +++ b/backend/src/module/notification/plugin/bark.py @@ -1,8 +1,7 @@ import logging -from module.network import RequestContent from module.models import Notification - +from module.network import RequestContent logger = logging.getLogger(__name__) diff --git a/backend/src/module/notification/plugin/server_chan.py b/backend/src/module/notification/plugin/server_chan.py index 9903ed3e..5e5ca495 100644 --- a/backend/src/module/notification/plugin/server_chan.py +++ b/backend/src/module/notification/plugin/server_chan.py @@ -1,7 +1,7 @@ import logging -from module.network import RequestContent from module.models import Notification +from module.network import RequestContent logger = logging.getLogger(__name__) diff --git a/backend/src/module/notification/plugin/slack.py b/backend/src/module/notification/plugin/slack.py index f4da8a2d..2100a812 100644 --- a/backend/src/module/notification/plugin/slack.py +++ b/backend/src/module/notification/plugin/slack.py @@ -1,7 +1,7 @@ import logging -from module.network import RequestContent from module.models import Notification +from module.network import RequestContent logger = logging.getLogger(__name__) diff --git a/backend/src/module/notification/plugin/telegram.py b/backend/src/module/notification/plugin/telegram.py index b269aea3..717f265b 100644 --- a/backend/src/module/notification/plugin/telegram.py +++ b/backend/src/module/notification/plugin/telegram.py @@ -1,7 +1,7 @@ import logging -from module.network import RequestContent from module.models import Notification +from module.network import RequestContent logger = logging.getLogger(__name__) diff --git a/backend/src/module/notification/plugin/wecom.py b/backend/src/module/notification/plugin/wecom.py index dbd906c4..01c4635f 100644 --- a/backend/src/module/notification/plugin/wecom.py +++ b/backend/src/module/notification/plugin/wecom.py @@ -1,7 +1,7 @@ import logging -from module.network import RequestContent from module.models import Notification +from module.network import RequestContent logger = logging.getLogger(__name__) diff --git a/backend/src/module/parser/analyser/__init__.py b/backend/src/module/parser/analyser/__init__.py index 433a62d7..da70a3f3 100644 --- a/backend/src/module/parser/analyser/__init__.py +++ b/backend/src/module/parser/analyser/__init__.py @@ -1,3 +1,4 @@ from .raw_parser import raw_parser -from .torrent_parser import torrent_parser from .tmdb_parser import tmdb_parser +from .torrent_parser import torrent_parser +from .mikan_parser import mikan_parser diff --git a/backend/src/module/parser/analyser/bgm_parser.py b/backend/src/module/parser/analyser/bgm_parser.py index af345270..eb87f509 100644 --- a/backend/src/module/parser/analyser/bgm_parser.py +++ b/backend/src/module/parser/analyser/bgm_parser.py @@ -1,7 +1,8 @@ from module.network import RequestContent -search_url = lambda e: f"https://api.bgm.tv/search/subject/{e}?responseGroup=large" +def search_url(e): + return f"https://api.bgm.tv/search/subject/{e}?responseGroup=large" def bgm_parser(title): diff --git a/backend/src/module/parser/analyser/mikan_parser.py b/backend/src/module/parser/analyser/mikan_parser.py new file mode 100644 index 00000000..7cc30d20 --- /dev/null +++ b/backend/src/module/parser/analyser/mikan_parser.py @@ -0,0 +1,21 @@ +from bs4 import BeautifulSoup +from urllib3.util import parse_url + +from module.network import RequestContent + + +def mikan_parser(homepage: str): + root_path = parse_url(homepage).host + with RequestContent() as req: + content = req.get_html(homepage) + soup = BeautifulSoup(content, "html.parser") + poster_div = soup.find("div", {"class": "bangumi-poster"}) + poster_style = poster_div.get("style") + official_title = soup.select_one( + 'p.bangumi-title a[href^="/Home/Bangumi/"]' + ).text + if poster_style: + poster_path = poster_style.split("url('")[1].split("')")[0] + poster_link = f"https://{root_path}{poster_path}" + return poster_link, official_title + return "", "" diff --git a/backend/src/module/parser/analyser/raw_parser.py b/backend/src/module/parser/analyser/raw_parser.py index 5520af97..5de06089 100644 --- a/backend/src/module/parser/analyser/raw_parser.py +++ b/backend/src/module/parser/analyser/raw_parser.py @@ -94,23 +94,11 @@ def name_process(name: str): split = re.split("-", name) if len(split) == 1: split_space = split[0].split(" ") - language_pattern = [] - for item in split_space: - if re.search(r"[\u4e00-\u9fa5]{2,}", item) is not None: - language_pattern.append(1) - elif re.search(r"[a-zA-Z]{2,}", item) is not None: - language_pattern.append(0) - elif re.search(r"[\u0800-\u4e00]{2,}", item) is not None: - language_pattern.append(2) - split = [split_space[0]] - for i in range(1, len(split_space)): - # 如果当前字符串的语言与上一个字符串的语言相同 - if language_pattern[i] == language_pattern[i - 1]: - # 合并这两个字符串 - split[-1] += " " + split_space[i] - else: - # 否则,将当前字符串添加到结果列表中 - split.append(split_space[i]) + for idx, item in enumerate(split_space): + if re.search(r"^[\u4e00-\u9fa5]{2,}", item) is not None: + split_space.remove(item) + split = [item.strip(), " ".join(split_space).strip()] + break for item in split: if re.search(r"[\u0800-\u4e00]{2,}", item) and not name_jp: name_jp = item.strip() @@ -118,8 +106,6 @@ def name_process(name: str): name_zh = item.strip() elif re.search(r"[a-zA-Z]{3,}", item) and not name_en: name_en = item.strip() - if name_en not in name: - name_en = None return name_en, name_zh, name_jp @@ -196,5 +182,5 @@ def raw_parser(raw: str) -> Episode | None: if __name__ == "__main__": - title = "【极影字幕·毁片党】LoveLive! SunShine!! 幻日的夜羽 -SUNSHINE in the MIRROR- 第01集 TV版 HEVC_opus 1080p" + title = "[动漫国字幕组&LoliHouse] THE MARGINAL SERVICE - 08 [WebRip 1080p HEVC-10bit AAC][简繁内封字幕]" print(raw_parser(title)) diff --git a/backend/src/module/parser/analyser/tmdb_parser.py b/backend/src/module/parser/analyser/tmdb_parser.py index 879dae68..d57541f8 100644 --- a/backend/src/module/parser/analyser/tmdb_parser.py +++ b/backend/src/module/parser/analyser/tmdb_parser.py @@ -2,8 +2,11 @@ import re import time from dataclasses import dataclass -from module.network import RequestContent from module.conf import TMDB_API +from module.network import RequestContent + + +TMDB_URL = "https://api.themoviedb.org" @dataclass @@ -14,16 +17,18 @@ class TMDBInfo: season: list[dict] last_season: int year: str + poster_link: str = None LANGUAGE = {"zh": "zh-CN", "jp": "ja-JP", "en": "en-US"} -search_url = ( - lambda e: f"https://api.themoviedb.org/3/search/tv?api_key={TMDB_API}&page=1&query={e}&include_adult=false" -) -info_url = ( - lambda e, key: f"https://api.themoviedb.org/3/tv/{e}?api_key={TMDB_API}&language={LANGUAGE[key]}" -) + +def search_url(e): + return f"{TMDB_URL}/3/search/tv?api_key={TMDB_API}&page=1&query={e}&include_adult=false" + + +def info_url(e, key): + return f"{TMDB_URL}/3/tv/{e}?api_key={TMDB_API}&language={LANGUAGE[key]}" def is_animation(tv_id, language) -> bool: @@ -36,7 +41,7 @@ def is_animation(tv_id, language) -> bool: return False -def get_season(seasons: list) -> int: +def get_season(seasons: list) -> tuple[int, str]: ss = [s for s in seasons if s["air_date"] is not None] ss = sorted(ss, key=lambda e: e.get("air_date"), reverse=True) for season in ss: @@ -45,7 +50,7 @@ def get_season(seasons: list) -> int: [year, _, _] = date now_year = time.localtime().tm_year if int(year) <= now_year: - return int(re.findall(r"\d", season.get("season"))[0]) + return int(re.findall(r"\d", season.get("season"))[0]), season.get("poster_path") def tmdb_parser(title, language) -> TMDBInfo | None: @@ -71,10 +76,16 @@ def tmdb_parser(title, language) -> TMDBInfo | None: } for s in info_content.get("seasons") ] - last_season = get_season(season) + last_season, poster_path = get_season(season) + if poster_path is None: + poster_path = info_content.get("poster_path") original_title = info_content.get("original_name") official_title = info_content.get("name") year_number = info_content.get("first_air_date").split("-")[0] + if poster_path: + poster_link = "https://image.tmdb.org/t/p/w300" + poster_path + else: + poster_link = None return TMDBInfo( id, official_title, @@ -82,6 +93,11 @@ def tmdb_parser(title, language) -> TMDBInfo | None: season, last_season, str(year_number), + poster_link, ) else: return None + + +if __name__ == '__main__': + print(tmdb_parser("魔法禁书目录", "zh")) \ No newline at end of file diff --git a/backend/src/module/parser/analyser/torrent_parser.py b/backend/src/module/parser/analyser/torrent_parser.py index c4aa6c96..d4063526 100644 --- a/backend/src/module/parser/analyser/torrent_parser.py +++ b/backend/src/module/parser/analyser/torrent_parser.py @@ -1,7 +1,6 @@ -import re import logging -import os.path as unix_path -import ntpath as win_path +from pathlib import Path +import re from module.models import EpisodeFile, SubtitleFile @@ -23,11 +22,16 @@ SUBTITLE_LANG = { } -def split_path(torrent_path: str) -> str: - if PLATFORM == "Windows": - return win_path.split(torrent_path)[-1] - else: - return unix_path.split(torrent_path)[-1] +def get_path_basename(torrent_path: str) -> str: + """ + Returns the basename of a path string. + + :param torrent_path: A string representing a path to a file. + :type torrent_path: str + :return: A string representing the basename of the given path. + :rtype: str + """ + return Path(torrent_path).name def get_group(group_and_title) -> tuple[str | None, str]: @@ -64,7 +68,7 @@ def torrent_parser( season: int | None = None, file_type: str = "media", ) -> EpisodeFile | SubtitleFile: - media_path = split_path(torrent_path) + media_path = get_path_basename(torrent_path) for rule in RULES: if torrent_name: match_obj = re.match(rule, torrent_name, re.I) @@ -77,7 +81,7 @@ def torrent_parser( else: title, _ = get_season_and_title(title) episode = int(match_obj.group(2)) - suffix = unix_path.splitext(torrent_path)[-1] + suffix = Path(torrent_path).suffix if file_type == "media": return EpisodeFile( media_path=torrent_path, diff --git a/backend/src/module/parser/title_parser.py b/backend/src/module/parser/title_parser.py index 096b7010..89f0f2b2 100644 --- a/backend/src/module/parser/title_parser.py +++ b/backend/src/module/parser/title_parser.py @@ -1,9 +1,9 @@ import logging -from .analyser import raw_parser, torrent_parser, tmdb_parser - -from module.models import BangumiData from module.conf import settings +from module.models import Bangumi + +from .analyser import raw_parser, tmdb_parser, torrent_parser, mikan_parser logger = logging.getLogger(__name__) @@ -26,20 +26,18 @@ class TitleParser: @staticmethod def tmdb_parser(title: str, season: int, language: str): - official_title, tmdb_season, year = title, season, None tmdb_info = tmdb_parser(title, language) if tmdb_info: logger.debug(f"TMDB Matched, official title is {tmdb_info.title}") tmdb_season = tmdb_info.last_season if tmdb_info.last_season else season - official_title = tmdb_info.title - year = tmdb_info.year + return tmdb_info.title, tmdb_season, tmdb_info.year, tmdb_info.poster_link else: logger.warning(f"Cannot match {title} in TMDB. Use raw title instead.") logger.warning("Please change bangumi info manually.") - return official_title, tmdb_season, year + return title, season, None, None @staticmethod - def raw_parser(raw: str, rss_link: str) -> BangumiData | None: + def raw_parser(raw: str) -> Bangumi | None: language = settings.rss_parser.language try: episode = raw_parser(raw) @@ -60,7 +58,8 @@ class TitleParser: else: official_title = title_raw _season = episode.season - data = BangumiData( + logger.debug(f"RAW:{raw} >> {title_raw}") + return Bangumi( official_title=official_title, title_raw=title_raw, season=_season, @@ -71,12 +70,13 @@ class TitleParser: subtitle=episode.sub, eps_collect=False if episode.episode > 1 else True, offset=0, - filter=settings.rss_parser.filter, - rss_link=[rss_link], + filter=",".join(settings.rss_parser.filter), ) - logger.debug(f"RAW:{raw} >> {title_raw}") - return data except Exception as e: logger.debug(e) logger.warning(f"Cannot parse {raw}.") return None + + @staticmethod + def mikan_parser(homepage: str) -> tuple[str, str]: + return mikan_parser(homepage) diff --git a/backend/src/module/rss/__init__.py b/backend/src/module/rss/__init__.py index 0b9167ea..70406ee3 100644 --- a/backend/src/module/rss/__init__.py +++ b/backend/src/module/rss/__init__.py @@ -1,4 +1,2 @@ from .analyser import RSSAnalyser - - -analyser = RSSAnalyser() +from .engine import RSSEngine diff --git a/backend/src/module/rss/analyser.py b/backend/src/module/rss/analyser.py index 7cc52083..549fdc0a 100644 --- a/backend/src/module/rss/analyser.py +++ b/backend/src/module/rss/analyser.py @@ -1,37 +1,40 @@ -import re import logging +import re + +from .engine import RSSEngine -from module.network import RequestContent, TorrentInfo -from module.parser import TitleParser -from module.models import BangumiData -from module.database import BangumiDatabase from module.conf import settings +from module.models import Bangumi, Torrent, RSSItem, ResponseModel +from module.network import RequestContent +from module.parser import TitleParser logger = logging.getLogger(__name__) -class RSSAnalyser: - def __init__(self): - self._title_analyser = TitleParser() - with BangumiDatabase() as db: - db.update_table() - - def official_title_parser(self, data: BangumiData, mikan_title: str): - if settings.rss_parser.parser_type == "mikan": - data.official_title = mikan_title if mikan_title else data.official_title - elif settings.rss_parser.parser_type == "tmdb": - tmdb_title, season, year = self._title_analyser.tmdb_parser( - data.official_title, data.season, settings.rss_parser.language +class RSSAnalyser(TitleParser): + def official_title_parser(self, bangumi: Bangumi, rss: RSSItem, torrent: Torrent): + if rss.parser == "mikan": + try: + bangumi.poster_link, bangumi.official_title = self.mikan_parser( + torrent.homepage + ) + except AttributeError: + logger.warning("[Parser] Mikan torrent has no homepage info.") + pass + elif rss.parser == "tmdb": + tmdb_title, season, year, poster_link = self.tmdb_parser( + bangumi.official_title, bangumi.season, settings.rss_parser.language ) - data.official_title = tmdb_title - data.year = year - data.season = season + bangumi.official_title = tmdb_title + bangumi.year = year + bangumi.season = season + bangumi.poster_link = poster_link else: pass - data.official_title = re.sub(r"[/:.\\]", " ", data.official_title) + bangumi.official_title = re.sub(r"[/:.\\]", " ", bangumi.official_title) @staticmethod - def get_rss_torrents(rss_link: str, full_parse: bool = True) -> list: + def get_rss_torrents(rss_link: str, full_parse: bool = True) -> list[Torrent]: with RequestContent() as req: if full_parse: rss_torrents = req.get_torrents(rss_link) @@ -40,61 +43,53 @@ class RSSAnalyser: return rss_torrents def torrents_to_data( - self, torrents: list, rss_link: str, full_parse: bool = True + self, torrents: list[Torrent], rss: RSSItem, full_parse: bool = True ) -> list: new_data = [] for torrent in torrents: - data = self._title_analyser.raw_parser(raw=torrent.name, rss_link=rss_link) - if data and data.title_raw not in [i.title_raw for i in new_data]: - try: - poster_link, mikan_title = ( - torrent.poster_link, - torrent.official_title, - ) - except AttributeError: - poster_link, mikan_title = None, None - data.poster_link = poster_link - self.official_title_parser(data, mikan_title) + bangumi = self.raw_parser(raw=torrent.name) + if bangumi and bangumi.title_raw not in [i.title_raw for i in new_data]: + self.official_title_parser(bangumi=bangumi, rss=rss, torrent=torrent) if not full_parse: - return [data] - new_data.append(data) - logger.debug(f"[RSS] New title found: {data.official_title}") + return [bangumi] + new_data.append(bangumi) + logger.info(f"[RSS] New bangumi founded: {bangumi.official_title}") return new_data - def torrent_to_data( - self, torrent: TorrentInfo, rss_link: str | None = None - ) -> BangumiData: - data = self._title_analyser.raw_parser(raw=torrent.name, rss_link=rss_link) - if data: - try: - poster_link, mikan_title = ( - torrent.poster_link, - torrent.official_title, - ) - except AttributeError: - poster_link, mikan_title = None, None - data.poster_link = poster_link - self.official_title_parser(data, mikan_title) - return data + def torrent_to_data(self, torrent: Torrent, rss: RSSItem) -> Bangumi: + bangumi = self.raw_parser(raw=torrent.name) + if bangumi: + self.official_title_parser(bangumi=bangumi, rss=rss, torrent=torrent) + bangumi.rss_link = rss.url + return bangumi def rss_to_data( - self, rss_link: str, database: BangumiDatabase, full_parse: bool = True - ) -> list[BangumiData]: - rss_torrents = self.get_rss_torrents(rss_link, full_parse) - torrents_to_add = database.match_list(rss_torrents, rss_link) + self, rss: RSSItem, engine: RSSEngine, full_parse: bool = True + ) -> list[Bangumi]: + rss_torrents = self.get_rss_torrents(rss.url, full_parse) + torrents_to_add = engine.bangumi.match_list(rss_torrents, rss.url) if not torrents_to_add: logger.debug("[RSS] No new title has been found.") return [] # New List - new_data = self.torrents_to_data(torrents_to_add, rss_link, full_parse) + new_data = self.torrents_to_data(torrents_to_add, rss, full_parse) if new_data: + # Add to database + engine.bangumi.add_all(new_data) return new_data else: return [] - def link_to_data(self, link: str) -> BangumiData: - torrents = self.get_rss_torrents(link, False) + def link_to_data(self, rss: RSSItem) -> Bangumi | ResponseModel: + torrents = self.get_rss_torrents(rss.url, False) for torrent in torrents: - data = self.torrent_to_data(torrent, link) + data = self.torrent_to_data(torrent, rss) if data: return data + else: + return ResponseModel( + status=False, + status_code=406, + msg_en="No new title has been found.", + msg_zh="没有找到新的番剧。", + ) diff --git a/backend/src/module/rss/engine.py b/backend/src/module/rss/engine.py new file mode 100644 index 00000000..60f9e397 --- /dev/null +++ b/backend/src/module/rss/engine.py @@ -0,0 +1,147 @@ +import re +import logging + +from typing import Optional + +from module.models import Bangumi, RSSItem, Torrent, ResponseModel +from module.network import RequestContent +from module.downloader import DownloadClient + +from module.database import Database, engine + +logger = logging.getLogger(__name__) + + +class RSSEngine(Database): + def __init__(self, _engine=engine): + super().__init__(_engine) + self._to_refresh = False + + @staticmethod + def _get_torrents(rss: RSSItem) -> list[Torrent]: + with RequestContent() as req: + torrents = req.get_torrents(rss.url) + # Add RSS ID + for torrent in torrents: + torrent.rss_id = rss.id + return torrents + + def get_rss_torrents(self, rss_id: int) -> list[Torrent]: + rss = self.rss.search_id(rss_id) + if rss: + return self.torrent.search_rss(rss_id) + else: + return [] + + def add_rss(self, rss_link: str, name: str | None = None, aggregate: bool = True, parser: str = "mikan"): + if not name: + with RequestContent() as req: + name = req.get_rss_title(rss_link) + if not name: + return ResponseModel( + status=False, + status_code=406, + msg_en="Failed to get RSS title.", + msg_zh="无法获取 RSS 标题。", + ) + rss_data = RSSItem(name=name, url=rss_link, aggregate=aggregate, parser=parser) + if self.rss.add(rss_data): + return ResponseModel( + status=True, + status_code=200, + msg_en="RSS added successfully.", + msg_zh="RSS 添加成功。", + ) + else: + return ResponseModel( + status=False, + status_code=406, + msg_en="RSS added failed.", + msg_zh="RSS 添加失败。", + ) + + def disable_list(self, rss_id_list: list[int]): + for rss_id in rss_id_list: + self.rss.disable(rss_id) + return ResponseModel( + status=True, + status_code=200, + msg_en="Disable RSS successfully.", + msg_zh="禁用 RSS 成功。", + ) + + def enable_list(self, rss_id_list: list[int]): + for rss_id in rss_id_list: + self.rss.enable(rss_id) + return ResponseModel( + status=True, + status_code=200, + msg_en="Enable RSS successfully.", + msg_zh="启用 RSS 成功。", + ) + + def delete_list(self, rss_id_list: list[int]): + for rss_id in rss_id_list: + self.rss.delete(rss_id) + return ResponseModel( + status=True, + status_code=200, + msg_en="Delete RSS successfully.", + msg_zh="删除 RSS 成功。", + ) + + def pull_rss(self, rss_item: RSSItem) -> list[Torrent]: + torrents = self._get_torrents(rss_item) + new_torrents = self.torrent.check_new(torrents) + return new_torrents + + def match_torrent(self, torrent: Torrent) -> Optional[Bangumi]: + matched: Bangumi = self.bangumi.match_torrent(torrent.name) + if matched: + _filter = matched.filter.replace(",", "|") + if not re.search(_filter, torrent.name, re.IGNORECASE): + torrent.bangumi_id = matched.id + return matched + return None + + def refresh_rss(self, client: DownloadClient, rss_id: Optional[int] = None): + # Get All RSS Items + if not rss_id: + rss_items: list[RSSItem] = self.rss.search_active() + else: + rss_item = self.rss.search_id(rss_id) + rss_items = [rss_item] if rss_item else [] + # From RSS Items, get all torrents + logger.debug(f"[Engine] Get {len(rss_items)} RSS items") + for rss_item in rss_items: + new_torrents = self.pull_rss(rss_item) + # Get all enabled bangumi data + for torrent in new_torrents: + matched_data = self.match_torrent(torrent) + if matched_data: + if client.add_torrent(torrent, matched_data): + logger.debug(f"[Engine] Add torrent {torrent.name} to client") + torrent.downloaded = True + # Add all torrents to database + self.torrent.add_all(new_torrents) + + def download_bangumi(self, bangumi: Bangumi): + with RequestContent() as req: + torrents = req.get_torrents(bangumi.rss_link, bangumi.filter.replace(",", "|")) + if torrents: + with DownloadClient() as client: + client.add_torrent(torrents, bangumi) + self.torrent.add_all(torrents) + return ResponseModel( + status=True, + status_code=200, + msg_en=f"[Engine] Download {bangumi.official_title} successfully.", + msg_zh=f"下载 {bangumi.official_title} 成功。", + ) + else: + return ResponseModel( + status=False, + status_code=406, + msg_en=f"[Engine] Download {bangumi.official_title} failed.", + msg_zh=f"[Engine] 下载 {bangumi.official_title} 失败。", + ) diff --git a/backend/src/module/rss/filter.py b/backend/src/module/rss/filter.py deleted file mode 100644 index 8255dbde..00000000 --- a/backend/src/module/rss/filter.py +++ /dev/null @@ -1,57 +0,0 @@ -import logging - -from module.database import BangumiDatabase -from module.downloader import DownloadClient -from module.network import RequestContent -from module.conf import settings -from module.models import BangumiData - -logger = logging.getLogger(__name__) - - -def matched(torrent_title: str): - with BangumiDatabase() as db: - return db.match_torrent(torrent_title) - - -def save_path(data: BangumiData): - folder = ( - f"{data.official_title}({data.year})" if data.year else f"{data.official_title}" - ) - season = f"Season {data.season}" - return path.join( - settings.downloader.path, - folder, - season, - ) - - -def add_download(data: BangumiData, torrent: TorrentInfo): - torrent = { - "url": torrent.url, - "save_path": save_path(data), - } - with DownloadClient() as client: - client.add_torrent(torrent) - with TorrentDatabase() as db: - db.add_torrent(torrent) - - -def downloaded(torrent: TorrentInfo): - with TorrentDatabase() as db: - return db.if_downloaded(torrent) - - -def get_downloads(rss_link: str): - with RequestContent() as req: - torrents = req.get_torrents(rss_link) - for torrent in torrents: - if not downloaded(torrent): - data = matched(torrent.title) - if data: - add_download(data, torrent) - logger.info(f"Add {torrent.title} to download list") - else: - logger.debug(f"{torrent.title} not matched") - else: - logger.debug(f"{torrent.title} already downloaded") diff --git a/backend/src/module/rss/searcher.py b/backend/src/module/rss/searcher.py deleted file mode 100644 index 0d547bd2..00000000 --- a/backend/src/module/rss/searcher.py +++ /dev/null @@ -1,14 +0,0 @@ -from module.network import RequestContent -from module.conf import settings - - -class RSSSearcher(RequestContent): - def __search_url(self, keywords: str) -> str: - keywords.replace(" ", "+") - url = f"{settings.rss_parser.custom_url}/RSS/Search?keyword={keywords}" - return url - - def search_keywords(self, keywords: str) -> list[dict]: - url = self.__search_url(keywords) - torrents = self.get_torrents(url) - return torrents diff --git a/backend/src/module/searcher/__init__.py b/backend/src/module/searcher/__init__.py index 534573fe..9630e420 100644 --- a/backend/src/module/searcher/__init__.py +++ b/backend/src/module/searcher/__init__.py @@ -1 +1,2 @@ from .searcher import SearchTorrent +from .provider import SEARCH_CONFIG diff --git a/backend/src/module/searcher/plugin/__init__.py b/backend/src/module/searcher/plugin/__init__.py deleted file mode 100644 index 47852a16..00000000 --- a/backend/src/module/searcher/plugin/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -from .mikan import mikan_url - - -def search_url(site: str, keywords: list[str]): - if site == "mikan": - return mikan_url(keywords) - else: - raise NotImplementedError(f"site {site} is not supported") diff --git a/backend/src/module/searcher/plugin/mikan.py b/backend/src/module/searcher/plugin/mikan.py deleted file mode 100644 index 947066c8..00000000 --- a/backend/src/module/searcher/plugin/mikan.py +++ /dev/null @@ -1,12 +0,0 @@ -import re - -from module.conf import settings - - -def mikan_url(keywords: list[str]): - keyword = "+".join(keywords) - search_str = re.sub(r"[\W_ ]", "+", keyword) - url = f"{settings.rss_parser.custom_url}/RSS/Search?searchstr={search_str}" - if "://" not in url: - url = f"https://{url}" - return url diff --git a/backend/src/module/searcher/provider.py b/backend/src/module/searcher/provider.py new file mode 100644 index 00000000..318a22ea --- /dev/null +++ b/backend/src/module/searcher/provider.py @@ -0,0 +1,20 @@ +import re + +from module.models import RSSItem +from module.conf import SEARCH_CONFIG + + +def search_url(site: str, keywords: list[str]) -> RSSItem: + keyword = "+".join(keywords) + search_str = re.sub(r"[\W_ ]", "+", keyword) + if site in SEARCH_CONFIG.keys(): + url = re.sub(r"%s", search_str, SEARCH_CONFIG[site]) + parser = "mikan" if site == "mikan" else "tmdb" + rss_item = RSSItem( + url=url, + aggregate=False, + parser=parser, + ) + return rss_item + else: + raise ValueError(f"Site {site} is not supported") \ No newline at end of file diff --git a/backend/src/module/searcher/searcher.py b/backend/src/module/searcher/searcher.py index ad46f664..e38b7402 100644 --- a/backend/src/module/searcher/searcher.py +++ b/backend/src/module/searcher/searcher.py @@ -1,6 +1,11 @@ -from module.searcher.plugin import search_url +import json +from typing import TypeAlias + +from module.models import Bangumi, Torrent, RSSItem from module.network import RequestContent -from module.models import BangumiData, TorrentBase +from module.rss import RSSAnalyser + +from .provider import search_url SEARCH_KEY = [ "group_name", @@ -11,32 +16,35 @@ SEARCH_KEY = [ "dpi", ] +BangumiJSON: TypeAlias = str -class SearchTorrent(RequestContent): + +class SearchTorrent(RequestContent, RSSAnalyser): def search_torrents( - self, keywords: list[str], site: str = "mikan" - ) -> list[TorrentBase]: - url = search_url(site, keywords) - # TorrentInfo to TorrentBase - torrents = self.get_torrents(url) + self, rss_item: RSSItem, limit: int = 5 + ) -> list[Torrent]: + torrents = self.get_torrents(rss_item.url, limit=limit) + return torrents - def to_dict(): - for torrent in torrents: - yield { - "name": torrent.name, - "torrent_link": torrent.torrent_link, - "homepage": torrent.homepage, - } + def analyse_keyword(self, keywords: list[str], site: str = "mikan") -> BangumiJSON: + rss_item = search_url(site, keywords) + torrents = self.search_torrents(rss_item) + # yield for EventSourceResponse (Server Send) + exist_list = [] + for torrent in torrents: + bangumi = self.torrent_to_data(torrent=torrent, rss=rss_item) + if bangumi and bangumi not in exist_list: + exist_list.append(bangumi) + bangumi.rss_link = self.special_url(bangumi, site).url + yield json.dumps(bangumi.dict(), separators=(',', ':')) - return [TorrentBase(**d) for d in to_dict()] - - def search_season(self, data: BangumiData): + @staticmethod + def special_url(data: Bangumi, site: str) -> RSSItem: keywords = [getattr(data, key) for key in SEARCH_KEY if getattr(data, key)] - torrents = self.search_torrents(keywords) - return [torrent for torrent in torrents if data.title_raw in torrent.name] + url = search_url(site, keywords) + return url - -if __name__ == "__main__": - with SearchTorrent() as st: - for t in st.search_torrents(["魔法科高校の劣等生"]): - print(t) + def search_season(self, data: Bangumi, site: str = "mikan") -> list[Torrent]: + rss_item = self.special_url(data, site) + torrents = self.search_torrents(rss_item) + return [torrent for torrent in torrents if data.title_raw in torrent.name] \ No newline at end of file diff --git a/backend/src/module/security/__init__.py b/backend/src/module/security/__init__.py index 28f5d20e..e69de29b 100644 --- a/backend/src/module/security/__init__.py +++ b/backend/src/module/security/__init__.py @@ -1,2 +0,0 @@ -from .jwt import create_access_token -from .api import get_current_user, get_token_data, auth_user, update_user_info diff --git a/backend/src/module/security/api.py b/backend/src/module/security/api.py index 810ff15e..3b8cc510 100644 --- a/backend/src/module/security/api.py +++ b/backend/src/module/security/api.py @@ -1,38 +1,28 @@ -from fastapi import Depends, HTTPException, status +from fastapi import Depends, HTTPException, status, Cookie from fastapi.security import OAuth2PasswordBearer +from module.database import Database +from module.models.user import User, UserUpdate + from .jwt import verify_token - -from module.database.user import AuthDB -from module.models.user import User - oauth2_scheme = OAuth2PasswordBearer(tokenUrl="/api/v1/auth/login") +active_user = [] -async def get_current_user(token: str = Depends(oauth2_scheme)): + +async def get_current_user(token: str = Cookie(None)): if not token: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) - try: - payload = verify_token(token) - except Exception: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) + raise UNAUTHORIZED + payload = verify_token(token) if not payload: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid token" - ) + raise UNAUTHORIZED username = payload.get("sub") - with AuthDB() as user_db: - user = user_db.get_user(username) - if not user: - raise HTTPException( - status_code=status.HTTP_401_UNAUTHORIZED, detail="invalid username" - ) - return user + if not username: + raise UNAUTHORIZED + if username not in active_user: + raise UNAUTHORIZED + return username async def get_token_data(token: str = Depends(oauth2_scheme)): @@ -44,15 +34,23 @@ async def get_token_data(token: str = Depends(oauth2_scheme)): return payload -def update_user_info(user_data: User, current_user): +def update_user_info(user_data: UserUpdate, current_user): try: - with AuthDB() as db: - db.update_user(current_user.username, user_data) + with Database() as db: + db.user.update_user(current_user, user_data) return True except Exception as e: raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(e)) -def auth_user(username, password): - with AuthDB() as db: - db.auth_user(username, password) +def auth_user(user: User): + with Database() as db: + resp = db.user.auth_user(user) + if resp.status: + active_user.append(user.username) + return resp + + +UNAUTHORIZED = HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, detail="Unauthorized" +) diff --git a/backend/src/module/security/jwt.py b/backend/src/module/security/jwt.py index 23f711fd..35c832a9 100644 --- a/backend/src/module/security/jwt.py +++ b/backend/src/module/security/jwt.py @@ -1,9 +1,16 @@ from datetime import datetime, timedelta + +from jose import JWTError, jwt from passlib.context import CryptContext -from jose import jwt, JWTError -app_pwd_key = "auto_bangumi" +def generate_key(): + import secrets + + return secrets.token_urlsafe(32) + + +app_pwd_key = generate_key() app_pwd_algorithm = "HS256" # Hashing 密码 diff --git a/backend/src/module/update/__init__.py b/backend/src/module/update/__init__.py index 0044a5be..ca1f94c5 100644 --- a/backend/src/module/update/__init__.py +++ b/backend/src/module/update/__init__.py @@ -1 +1,4 @@ from .data_migration import data_migration +from .startup import start_up, first_run +from .version_check import version_check +from .cross_version import from_30_to_31 diff --git a/backend/src/module/update/cross_version.py b/backend/src/module/update/cross_version.py new file mode 100644 index 00000000..79f386ff --- /dev/null +++ b/backend/src/module/update/cross_version.py @@ -0,0 +1,26 @@ +import re +from urllib3.util import parse_url + +from module.rss import RSSEngine + + +def from_30_to_31(): + with RSSEngine() as db: + db.migrate() + # Update poster link + bangumis = db.bangumi.search_all() + rss_pool = [] + for bangumi in bangumis: + if bangumi.poster_link: + rss_link = bangumi.rss_link.split(",")[-1] + if rss_link not in rss_pool and not re.search(r"\d+.\d+.\d+.\d+", rss_link): + rss_pool.append(rss_link) + root_path = parse_url(rss_link).host + bangumi.poster_link = f"https://{root_path}{bangumi.poster_link}" + db.bangumi.update_all(bangumis) + for rss in rss_pool: + if "mybangumi" in rss.lower(): + aggregate = True + else: + aggregate = False + db.add_rss(rss_link=rss, aggregate=aggregate) diff --git a/backend/src/module/update/data_migration.py b/backend/src/module/update/data_migration.py index 21dd72f6..f9775579 100644 --- a/backend/src/module/update/data_migration.py +++ b/backend/src/module/update/data_migration.py @@ -1,20 +1,24 @@ -import os - -from module.models import BangumiData +from module.conf import LEGACY_DATA_PATH +from module.rss import RSSEngine +from module.models import Bangumi from module.utils import json_config -from module.database import BangumiDatabase def data_migration(): - if not os.path.isfile("data/data.json"): + if not LEGACY_DATA_PATH.exists(): return False - old_data = json_config.load("data/data.json") + old_data = json_config.load(LEGACY_DATA_PATH) infos = old_data["bangumi_info"] rss_link = old_data["rss_link"] new_data = [] for info in infos: - new_data.append(BangumiData(**info, rss_link=[rss_link])) - with BangumiDatabase() as database: - database.update_table() - database.insert_list(new_data) - os.remove("data/data.json") + new_data.append(Bangumi(**info, rss_link=rss_link)) + with RSSEngine() as engine: + engine.bangumi.add_all(new_data) + engine.add_rss(rss_link) + LEGACY_DATA_PATH.unlink(missing_ok=True) + + +def database_migration(): + with RSSEngine() as engine: + engine.migrate() diff --git a/backend/src/module/update/rss.py b/backend/src/module/update/rss.py new file mode 100644 index 00000000..59e3e59c --- /dev/null +++ b/backend/src/module/update/rss.py @@ -0,0 +1,6 @@ +from module.rss import RSSEngine + + +def update_main_rss(rss_link: str): + with RSSEngine() as engine: + engine.add_rss(rss_link, "main", True) diff --git a/backend/src/module/update/startup.py b/backend/src/module/update/startup.py new file mode 100644 index 00000000..a80120c0 --- /dev/null +++ b/backend/src/module/update/startup.py @@ -0,0 +1,17 @@ +import logging + +from module.rss import RSSEngine + +logger = logging.getLogger(__name__) + + +def start_up(): + with RSSEngine() as engine: + engine.create_table() + engine.user.add_default_user() + + +def first_run(): + with RSSEngine() as engine: + engine.create_table() + engine.user.add_default_user() diff --git a/backend/src/module/update/version_check.py b/backend/src/module/update/version_check.py new file mode 100644 index 00000000..f3a89197 --- /dev/null +++ b/backend/src/module/update/version_check.py @@ -0,0 +1,27 @@ +import semver + +from module.conf import VERSION, VERSION_PATH + + +def version_check() -> bool: + if VERSION == "DEV_VERSION": + return True + if not VERSION_PATH.exists(): + with open(VERSION_PATH, "w") as f: + f.write(VERSION + "\n") + return False + else: + with open(VERSION_PATH, "r+") as f: + # Read last version + versions = f.readlines() + last_version = versions[-1] + last_ver = semver.VersionInfo.parse(last_version) + now_ver = semver.VersionInfo.parse(VERSION) + if now_ver.minor == last_ver.minor: + return True + else: + if now_ver.minor > last_ver.minor: + f.write(VERSION + "\n") + return False + else: + return True diff --git a/backend/src/module/utils/bangumi_data.py b/backend/src/module/utils/bangumi_data.py index d688be50..eea436a3 100644 --- a/backend/src/module/utils/bangumi_data.py +++ b/backend/src/module/utils/bangumi_data.py @@ -1,5 +1,3 @@ import logging -from .json_config import save, load - logger = logging.getLogger(__name__) diff --git a/backend/src/module/utils/json_config.py b/backend/src/module/utils/json_config.py index fdc974ca..2b060935 100644 --- a/backend/src/module/utils/json_config.py +++ b/backend/src/module/utils/json_config.py @@ -1,4 +1,5 @@ import json + import requests diff --git a/backend/src/test/test_database.py b/backend/src/test/test_database.py new file mode 100644 index 00000000..bb2babf7 --- /dev/null +++ b/backend/src/test/test_database.py @@ -0,0 +1,78 @@ +from sqlmodel import create_engine, SQLModel +from sqlmodel.pool import StaticPool + +from module.database.combine import Database +from module.models import Bangumi, Torrent, RSSItem + + +# sqlite mock engine +engine = create_engine( + "sqlite://", connect_args={"check_same_thread": False}, poolclass=StaticPool +) + + +def test_bangumi_database(): + test_data = Bangumi( + official_title="无职转生,到了异世界就拿出真本事", + year="2021", + title_raw="Mushoku Tensei", + season=1, + season_raw="", + group_name="Lilith-Raws", + dpi="1080p", + source="Baha", + subtitle="CHT", + eps_collect=False, + offset=0, + filter="720p,\\d+-\\d+", + rss_link="test", + poster_link="/test/test.jpg", + added=False, + rule_name=None, + save_path="downloads/无职转生,到了异世界就拿出真本事/Season 1", + deleted=False, + ) + with Database(engine) as db: + db.create_table() + # insert + db.bangumi.add(test_data) + assert db.bangumi.search_id(1) == test_data + + # update + test_data.official_title = "无职转生,到了异世界就拿出真本事II" + db.bangumi.update(test_data) + assert db.bangumi.search_id(1) == test_data + + # search poster + assert db.bangumi.match_poster("无职转生,到了异世界就拿出真本事II (2021)") == "/test/test.jpg" + + # match torrent + result = db.bangumi.match_torrent("[Lilith-Raws] 无职转生,到了异世界就拿出真本事 / Mushoku Tensei - 11 [Baha][WEB-DL][1080p][AVC AAC][CHT][MP4]") + assert result.official_title == "无职转生,到了异世界就拿出真本事II" + + # delete + db.bangumi.delete_one(1) + assert db.bangumi.search_id(1) is None + + +def test_torrent_database(): + test_data = Torrent( + name="[Sub Group]test S02 01 [720p].mkv", + url="https://test.com/test.mkv", + ) + with Database(engine) as db: + # insert + db.torrent.add(test_data) + assert db.torrent.search(1) == test_data + + # update + test_data.downloaded = True + db.torrent.update(test_data) + assert db.torrent.search(1) == test_data + + +def test_rss_database(): + rss_url = "https://test.com/test.xml" + + with Database(engine) as db: + db.rss.add(RSSItem(url=rss_url)) diff --git a/backend/src/test/test_raw_parser.py b/backend/src/test/test_raw_parser.py index 39f1944c..b4c3b446 100644 --- a/backend/src/test/test_raw_parser.py +++ b/backend/src/test/test_raw_parser.py @@ -69,22 +69,3 @@ def test_raw_parser(): assert info.resolution == "720P" assert info.episode == 5 assert info.season == 1 - - content = "【极影字幕·毁片党】LoveLive! SunShine!! 幻日的夜羽 -SUNSHINE in the MIRROR- 第01集 TV版 HEVC_opus 1080p " - info = raw_parser(content) - assert info.group == "极影字幕·毁片党" - assert info.title_zh == "幻日的夜羽" - assert info.title_en == "LoveLive! SunShine!!" - assert info.resolution == "1080p" - assert info.episode == 1 - assert info.season == 1 - - content = "[ANi] BLEACH 死神 千年血战篇-诀别谭- - 14 [1080P][Baha][WEB-DL][AAC AVC][CHT][MP4]" - info = raw_parser(content) - assert info.group == "ANi" - assert info.title_en == "BLEACH" - assert info.title_zh == "死神 千年血战篇-诀别谭-" - assert info.resolution == "1080P" - assert info.episode == 14 - assert info.season == 1 - diff --git a/backend/src/test/test_rss_engine.py b/backend/src/test/test_rss_engine.py new file mode 100644 index 00000000..cda69f6e --- /dev/null +++ b/backend/src/test/test_rss_engine.py @@ -0,0 +1,18 @@ +from module.rss.engine import RSSEngine + +from .test_database import engine as e + + +def test_rss_engine(): + with RSSEngine(e) as engine: + rss_link = "https://mikanani.me/RSS/Bangumi?bangumiId=2353&subgroupid=552" + + engine.add_rss(rss_link, aggregate=False) + + result = engine.rss.search_active() + assert result[1].name == "Mikan Project - 无职转生~到了异世界就拿出真本事~" + + new_torrents = engine.pull_rss(result[1]) + torrent = new_torrents[0] + assert torrent.name == "[Lilith-Raws] 无职转生,到了异世界就拿出真本事 / Mushoku Tensei - 11 [Baha][WEB-DL][1080p][AVC AAC][CHT][MP4]" + diff --git a/backend/src/test/test_tmdb.py b/backend/src/test/test_tmdb.py new file mode 100644 index 00000000..3c1db416 --- /dev/null +++ b/backend/src/test/test_tmdb.py @@ -0,0 +1,13 @@ +from module.parser.analyser.tmdb_parser import tmdb_parser + + +def test_tmdb_parser(): + bangumi_title = "海盗战记" + bangumi_year = "2019" + bangumi_season = 2 + + tmdb_info = tmdb_parser(bangumi_title, "zh") + + assert tmdb_info.title == "冰海战记" + assert tmdb_info.year == bangumi_year + assert tmdb_info.last_season == bangumi_season diff --git a/backend/src/test/test_torrent_parser.py b/backend/src/test/test_torrent_parser.py index 54832c7f..10e6a546 100644 --- a/backend/src/test/test_torrent_parser.py +++ b/backend/src/test/test_torrent_parser.py @@ -1,4 +1,8 @@ +import sys + +import pytest from module.parser.analyser import torrent_parser +from module.parser.analyser.torrent_parser import get_path_basename def test_torrent_parser(): @@ -67,3 +71,18 @@ def test_torrent_parser(): assert bf.title == "放学后失眠的你-Kimi wa Houkago Insomnia" assert bf.season == 1 assert bf.episode == 6 + + +class TestGetPathBasename: + def test_regular_path(self): + assert get_path_basename("/path/to/file.txt") == "file.txt" + + def test_empty_path(self): + assert get_path_basename("") == "" + + def test_path_with_trailing_slash(self): + assert get_path_basename("/path/to/folder/") == "folder" + + @pytest.mark.skipif(not sys.platform.startswith("win"), reason="Windows specific") + def test_windows_path(self): + assert get_path_basename("C:\\path\\to\\file.txt") == "file.txt" diff --git a/dev.sh b/dev.sh deleted file mode 100644 index 323fc3c2..00000000 --- a/dev.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/bash - - -# This script is used to run the development environment. - -python3 -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple install -r requirements.txt - -cd src || exit - -CONFIG_DIR="config" - -if [ ! -d "$CONFIG_DIR" ]; then - echo "The directory '$CONFIG_DIR' is missing." - mkdir config -fi - -VERSION_FILE="module/__version__.py" - -if [ ! -f "$VERSION_FILE" ]; then - echo "The file '$VERSION_FILE' is missing." - echo "VERSION='DEV_VERSION'" >> "$VERSION_FILE" -fi - -python3 main.py \ No newline at end of file diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts new file mode 100644 index 00000000..0029f92f --- /dev/null +++ b/docs/.vitepress/config.ts @@ -0,0 +1,179 @@ +import { defineConfig } from "vitepress"; + +const version = `v3.0` + +// https://vitepress.dev/reference/site-config +// @ts-ignore +export default defineConfig({ + title: "AutoBangumi", + description: "从 Mikan Project 全自动追番下载整理", + + head: [ + ['link', { rel: 'icon', type: 'image/svg+xml', href: '/light-logo.svg' }], + ['meta', { property: 'og:image', content: '/social.png' }], + ['meta', { property: 'og:site_name', content: 'AutoBangumi' }], + ['meta', { property: 'og:url', content: 'https://www.autobangumi.org' }], + ["script", { src: 'https://www.googletagmanager.com/gtag/js?id=G-3Z8W6WMN7J' }], + ["script", {}, "window.dataLayer = window.dataLayer || [];\nfunction gtag(){dataLayer.push(arguments);}\ngtag('js', new Date());\ngtag('config', 'G-3Z8W6WMN7J');"], + ], + + themeConfig: { + // https://vitepress.dev/reference/default-theme-config + logo: { + dark: '/dark-logo.svg', + light: '/light-logo.svg', + }, + + editLink: { + pattern: 'https://github.com/vitejs/vite/blob/3.1-dev/docs/:path', + text: 'Edit this page', + }, + + search: { + provider: 'local' + }, + + socialLinks: [ + { icon: "github", link: "https://github.com/EstrellaXD/Auto_Bangumi" }, + { + icon: { + svg: 'Telegram' + }, + link: "https://t.me/autobangumi" + }, + ], + + nav: [ + { text: "项目说明", link: "/home/" }, + { text: "快速开始", link: "/deploy/quick-start" }, + { text: "排错流程", link: "/faq/排错流程" }, + { text: "常见问题", link: "/faq/常见问题" }, + ], + + footer: { + message: `AutoBangumi Released under the MIT License. (latest: ${version})`, + copyright: 'Copyright © 2021-present @EstrellaXD & AutoBangumi Contributors', + }, + + sidebar: [ + { + items: [ + { + text: "项目说明", + link: "/home/", + }, + { + text: "快速开始", + link: "/deploy/quick-start", + }, + ], + }, + { + text: "部署", + items: [ + { + text: "Docker-cli 部署", + link: "/deploy/docker-cli", + }, + { + text: "Docker-Compose 部署", + link: "/deploy/docker-compose", + }, + { + text: "群晖NAS", + link: "/deploy/dsm", + }, + { + text: "WSL", + link: "/deploy/wsl", + }, + ], + }, + { + text: "源码运行", + items: [ + { + text: "Windows 本地部署", + link: "/deploy/windows", + }, + { + text: "Unix 本地部署", + link: "/deploy/unix", + }, + ], + }, + { + text: "配置说明", + items: [ + { + text: "获取 RSS 订阅链接", + link: "/config/rss", + }, + { + text: "主程序配置", + link: "/config/program", + }, + { + text: "下载器配置", + link: "/config/downloader", + }, + { + text: "解析器配置", + link: "/config/parser", + }, + { + text: "推送器配置", + link: "/config/notifier", + }, + { + text: "代理配置", + link: "/config/proxy", + } + ] + }, + { + text: "WebUI 使用说明", + link: "/usage/webui", + }, + { + text: "FAQ", + items: [ + { + text: "排错流程", + link: "/faq/排错流程", + }, + { + text: "常见问题", + link: "/faq/常见问题", + }, + { + text: "网络问题", + link: "/faq/mikan-network", + } + ], + }, + { + text: "更新日志", + items: [ + { + text: "3.0 更新说明", + link: "/changelog/3.0", + }, + { + text: "2.6 更新说明", + link: "/changelog/2.6", + }, + ], + }, + { + text: "开发者文档", + items: [ + { + text: "贡献指南", + link: "/dev/", + }, + ] + } + ], + }, +}); diff --git a/docs/.vitepress/theme/components/HomePreviewWebUI.vue b/docs/.vitepress/theme/components/HomePreviewWebUI.vue new file mode 100644 index 00000000..aaaa4871 --- /dev/null +++ b/docs/.vitepress/theme/components/HomePreviewWebUI.vue @@ -0,0 +1,50 @@ + + + + + \ No newline at end of file diff --git a/docs/.vitepress/theme/index.ts b/docs/.vitepress/theme/index.ts new file mode 100644 index 00000000..6beadcc2 --- /dev/null +++ b/docs/.vitepress/theme/index.ts @@ -0,0 +1,45 @@ +// https://vitepress.dev/guide/custom-theme +import { + h, + onMounted, + watch, + nextTick, +} from 'vue' +import Theme from 'vitepress/theme' +import { useRoute } from 'vitepress' +import mediumZoom from 'medium-zoom' +import HomePreviewWebUI from './components/HomePreviewWebUI.vue' + +import './style.css' + +export default { + extends: Theme, + Layout: () => { + return h(Theme.Layout, null, { + // https://vitepress.dev/guide/extending-default-theme#layout-slots + 'home-features-after': () => h(HomePreviewWebUI), + }) + }, + setup() { + const route = useRoute() + const initZoom = () => { + /** + * Allow images to be zoomed in on click + * https://github.com/vuejs/vitepress/issues/854 + */ + mediumZoom('[data-zoomable]', { background: 'var(--vp-c-bg)' }) + } + + onMounted(() => { + initZoom() + }) + + watch( + () => route.path, + () => nextTick(initZoom), + ) + }, + enhanceApp({ app, router, siteData }) { + // ... + } +} diff --git a/docs/.vitepress/theme/style.css b/docs/.vitepress/theme/style.css new file mode 100644 index 00000000..a5f9baec --- /dev/null +++ b/docs/.vitepress/theme/style.css @@ -0,0 +1,110 @@ +/** + * Customize default theme styling by overriding CSS variables: + * https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css + */ + +/** + * Colors + * -------------------------------------------------------------------------- */ + + :root { + --vp-c-brand: #7B65D6; + --vp-c-brand-light: #7162AE; + --vp-c-brand-lighter: #8D7FC2; + --vp-c-brand-lightest: #8E8A9C; + --vp-c-brand-dark: #4E3C94; + --vp-c-brand-darker: #281E52; + --vp-c-brand-dimm: rgba(100, 108, 255, 0.08); +} + +/** + * Component: Button + * -------------------------------------------------------------------------- */ + +:root { + --vp-button-brand-border: var(--vp-c-brand-light); + --vp-button-brand-text: var(--vp-c-white); + --vp-button-brand-bg: var(--vp-c-brand); + --vp-button-brand-hover-border: var(--vp-c-brand-light); + --vp-button-brand-hover-text: var(--vp-c-white); + --vp-button-brand-hover-bg: var(--vp-c-brand-light); + --vp-button-brand-active-border: var(--vp-c-brand-light); + --vp-button-brand-active-text: var(--vp-c-white); + --vp-button-brand-active-bg: var(--vp-button-brand-bg); +} + +/** + * Component: Home + * -------------------------------------------------------------------------- */ + +:root { + --vp-home-hero-name-color: transparent; + --vp-home-hero-name-background: -webkit-linear-gradient( + 120deg, + #b42ff1 30%, + #441bd9 + ); + + --vp-home-hero-image-background-image: linear-gradient( + -45deg, + #b42ff1bb 50%, + #4794ffbb 50% + ); + --vp-home-hero-image-filter: blur(40px); +} + +@media (min-width: 640px) { + :root { + --vp-home-hero-image-filter: blur(56px); + } +} + +@media (min-width: 960px) { + :root { + --vp-home-hero-image-filter: blur(72px); + } +} + +/** + * Component: Custom Block + * -------------------------------------------------------------------------- */ + +:root { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-darker); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +.dark { + --vp-custom-block-tip-border: var(--vp-c-brand); + --vp-custom-block-tip-text: var(--vp-c-brand-lightest); + --vp-custom-block-tip-bg: var(--vp-c-brand-dimm); +} + +/** + * Component: Algolia + * -------------------------------------------------------------------------- */ + +.DocSearch { + --docsearch-primary-color: var(--vp-c-brand) !important; +} + +/** + * Component: medium-zoom + * -------------------------------------------------------------------------- */ + + +.medium-zoom--opened .medium-zoom-overlay { + z-index: 20; +} + +.medium-zoom--opened .medium-zoom-image { + z-index: 21; +} + +.vp-doc .ab-shadow-card { + box-shadow: 0 10px 30px -10px rgba(0,0,0,0.2), + 0 0 2px rgba(0,0,0,0.2), + 0 20px 30px -20px rgba(0,0,0,0.4); + border-radius: 10px; +} diff --git a/docs/changelog/2.6.md b/docs/changelog/2.6.md new file mode 100644 index 00000000..5c553a0e --- /dev/null +++ b/docs/changelog/2.6.md @@ -0,0 +1,139 @@ +# 2.6 版本更新说明 + +## 如何从老版本更新的注意事项 + +从 2.6 版本开始,AutoBangumi (以下简称 AB)的配置文件将会从环境变量更改为 `config.json` 升级之前需要注意以下事项。 + +### 环境变量继承 + +老的环境变量会在升级到 2.6 版本后第一次启动时自动转换为 `config.json`,生成的 `config.json` 会放在 `/app/config` 文件夹内。 +当你已经映射了 `/app/config` 文件夹之后,老的环境变量将不对 AB 运行产生影响,但是你可以通过删除 `config.json` 来重新使用环境变量生成配置。 + +### 容器 Volume 映射 + +2.6 版本之后需要映射的文件夹有: + +- `/app/config`:配置文件夹,包含 `config.json` +- `/app/data`:数据文件夹,包含 `bangumi.json` 等 + +### 数据文件 + +新版本进行了大规模更新,因此我们不建议你使用老的数据文件,AB 会自动生成新的数据文件 `bangumi.json` 保存在 `/app/data` 中。 + +但是不用担心,QB 不会重复下载已经下载过的番剧。 + +### 后续配置更改 + +现在 AB 可以在 WebUI 中直接编辑配置了,编辑完成之后只需要重启容器就可以立刻生效。 + +## 如何升级 + +### Docker compose + +你可以用老的 docker-compose.yml 文件升级。 + +```bash +docker compose stop autobangumi +docker compose pull autobangumi +``` + +然后修改 docker-compose.yml 文件,添加 `volumes` 映射。 + +```yaml +version: "3.8" + +services: + autobangumi: + image: estrellaxd/auto_bangumi:latest + container_name: autobangumi + restart: unless-stopped + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Shanghai + volumes: + - /path/to/config:/app/config + - /path/to/data:/app/data + networks: + - bridge + dns: + - 223.5.5.5 +``` + +然后拉起 AB 即可 + +```bash +docker compose up -d autobangumi +``` + +### Portainer + +你可以在 `Portainer` 中修改映射文件地址之后点击 `Recreate` 即可完成升级 + +### 如果升级出现了问题需要怎么做 + +由于每个人配置可能不尽相同,现在升级可能会出现程序无法运行的问题,此时删除掉所有以前的数据以及生成的配置文件后重启容器。 +然后在 WebUI 中重新配置一下即可。 + + +## 新版本特性 + +### 配置方式更改 + +2.6 版本之后配置程序的方式从修改 Docker 中的环境变量更改为修改 `config.json`。 +新版 WebUI 也提供了网页版修改配置的功能。可以访问 AB 地址,在左侧边栏找到 `配置` 即可修改。 +修改完成之后重启容器即可。 + +### 自定义反向代理 URL 和 AB 作为反代中转 + +为了应对 [蜜柑计划](https://mikanani.me) 无法访问的情况,AB 增加了三种应对的方式。 + +1. HTTP 以及 Socks 代理 + + 老版本的 AB 就有这项功能,升级到 2.6 版本之后只需要在 WebUI 中检查代理配置即可正常访问蜜柑计划。 + + 不过这时候 qBittorrent 无法正常访问蜜柑计划的 RSS 和种子地址,因此需要在 qBittorrent 中添加代理。详情可以查看 #198 + +2. 自定义反向代理 URL + + 2.6 版本的 AB 在配置中增加了 `custom_url` 选项,可以自定义反向代理的 URL。 + 可以在配置中设置为自己正确设置的反代 URL。这样 AB 就会使用自定义的 URL 来访问蜜柑计划。并且 QB 也可以正常下载。 + +3. AB 作为反代中转 + + 在 AB 配置代理之后,AB 自身可以作为本地的反代中转。不过目前仅开放 RSS 相关功能的反代。 + 这时候只需要把 `custom_url` 设置为 `http://abhost:abport` 即可。 `abhost` 为 AB 的 IP 地址,`abport` 为 AB 的端口。 + 此时 AB 会把自身地址推送给 qBittorrent,qBittorrent 会使用 AB 的地址作为反代来访问蜜柑计划。 + + 请注意,此时如果你没有用 NGINX 等工具对 AB 进行反代,请填入 `http://` 来保证程序正常运行。 + +**注意事项** + +需要注意的是,如果 AB 和 QB 在同一个容器中,请不要用 `127.0.0.1` 或者 `localhost`,因为这样会导致 AB QB 无法互相访问。 +如果在同一个网络中,可以使用容器名寻址的方式来访问。如 `http://autobangumi:7892`。 + +也可以使用 Docker 路由地址访问如 `http://172.17.0.1:7892`。 + +如果在不同宿主机中,可以使用宿主机 IP 地址访问。 + +### 合集以及文件夹重命名 + +AB 现在可以对合集以及文件夹内的文件进行重命名了,此时 AB 会把文件夹内的媒体文件重新放置到根目录中。 +需要注意的是,目前 AB 还依赖保存路径来判断季度信息和剧集信息,所以请按照 AB 的标准放置合集文件。 + +**2.6.4** 版本后,AB 可以对文件夹内的字幕进行重命名,不过该功能暂时在适配中。合集和字幕默认以 `pn` 格式重命名,暂时不提供调整选项。 + +**标准路径** + +``` +/downloads/Bangumi/剧集信息/Season 1/xxx +``` + +### 通知推送功能 + +AB 现在可以通过 `Telegram` 和 `ServerChan` 推送重命名完成的通知了。 + +在 WebUI 中,打开推送开关,并且填入所需的参数即可完成推送。 + +- Telegram 需要填入 Bot Token 和 Chat ID,具体如何获取请参看各类教程。 +- ServerChan 需要填入 Token,具体如何获取请参看各类教程。 \ No newline at end of file diff --git a/docs/changelog/3.0.md b/docs/changelog/3.0.md index f1c29d83..bf01da9b 100644 --- a/docs/changelog/3.0.md +++ b/docs/changelog/3.0.md @@ -1,4 +1,4 @@ -## New +# 3.0 更新说明 ### 全新的 WebUI diff --git a/docs/config/downloader.md b/docs/config/downloader.md new file mode 100644 index 00000000..afd0840d --- /dev/null +++ b/docs/config/downloader.md @@ -0,0 +1,55 @@ +# 下载器设置 + +## WebUI 设置 + +![downloader](../image/config/downloader.png){width=500}{class=ab-shadow-card} + +
+ +- **Downloader Type** 为下载器类型,目前支持 qBittorrent 下载器,目前暂不支持修改。 +- **Host** 为下载器地址。[1](#下载器地址) +- **Download path** 为映射的下载器下载路径。[2](#下载器路径问题) +- **SSL** 为下载器是否使用 SSL。 + +## 常见问题 + +### 下载器地址 + +⚠️**请不要直接使用 127.0.0.1 或 localhost 作为下载器地址。** + +由于 AB 在官方教程中是以 **Bridge** 模式运行在 Docker 中的,如果你是用 127.0.0.1 或者 localhost 那么 AB 将会把这个地址解析为自身,而非下载器。 +- 如果此时你的 qBittorrent 也运行在 Docker 中,那么我们推荐你是用 Docker 的 **网关地址:172.17.0.1**。 +- 如果你的 qBittorrent 运行在宿主机上,那么你需要使用宿主机的 IP 地址。 + +如果你以 **Host** 模式运行 AB,那么你可以直接使用 127.0.0.1 代替 Docker 网关地址。 + +⚠️ Macvlan 会隔离容器的网络,此时如果你不做额外的网桥配置将无法访问同宿主机的其他容器或者主机本身。 + +### 下载器路径问题 + +AB 中配置的路径只是为了生成对应番剧文件路径,AB 本身不对路径下的文件做直接管理。 + +**下载路径** 到底写什么? + +这个参数只要和你 **下载器** 中的参数保持一致即可。 +- Docker:比如 qB 中是 `/downloads` 那就写 `/downloads/Bangumi`,`Bangumi`可以任意更改。 +- Linux/macOS:如果是 `/home/usr/downloads` 或者 `/User/UserName/Downloads` 只要在最后再加一行 `Bangumi` 就行。 +- Windows:`D:\Media\`, 改为 `D:\Media\Bangumi` + +## `config.json` 中的配置选项 + +在配置文件中对应选项如下: + +配置文件部分:`downloader` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|----------|-------------|------|-------------|--------------------| +| type | 下载器类型 | 字符串 | 下载器类型 | qbittorrent | +| host | 下载器地址 | 字符串 | 下载器地址 | 172.17.0.1:8080 | +| username | 下载器用户名 | 字符串 | 下载器用户名 | admin | +| password | 下载器密码 | 字符串 | 下载器密码 | adminadmin | +| path | 下载器下载路径 | 字符串 | 下载器下载路径 | /downloads/Bangumi | +| ssl | 下载器是否使用 SSL | 布尔值 | 下载器是否使用 SSL | false | + + + diff --git a/docs/config/notifier.md b/docs/config/notifier.md new file mode 100644 index 00000000..1603322d --- /dev/null +++ b/docs/config/notifier.md @@ -0,0 +1,34 @@ +# 通知配置 + +## WebUI 配置 + +![notification](../image/config/notifier.png){width=500}{class=ab-shadow-card} + +
+ +- **Enable** 为是否启用通知,如果不启用通知,下面的配置项将不会生效。 +- **Type** 为通知类型,目前支持: + - Telegram + - Wecom + - Bark + - ServerChan +- **Chat ID** 仅在使用 `telegram` 通知时需要填写。[Telegram Bot 获取 Chat ID][1] +- **Wecom**,chat_id参数框填写自建推送的url地址,同时需要在服务端增加[图文消息][2]类型。[Wecom酱配置说明][3] + +## `config.json` 中的配置选项 + +在配置文件中对应选项如下: + +配置文件部分:`notification` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|---------|------------|------|------------|----------| +| enable | 是否启用通知 | 布尔值 | 通知 | false | +| type | 通知类型 | 字符串 | 通知类型 | telegram | +| token | 通知 Token | 字符串 | 通知 Token | +| chat_id | 通知 Chat ID | 字符串 | 通知 Chat ID | + + +[1]: https://core.telegram.org/bots#6-botfather +[2]: https://github.com/umbors/wecomchan-alifun +[3]: https://github.com/easychen/wecomchan \ No newline at end of file diff --git a/docs/config/parser.md b/docs/config/parser.md new file mode 100644 index 00000000..b771c403 --- /dev/null +++ b/docs/config/parser.md @@ -0,0 +1,41 @@ +# 解析器设置 + +AB 的解析器用于解析聚合 RSS 链接,如果 RSS 有新条目更新,AB 就会解析标题并且生成自动下载规则。 + +## Webui 中的解析器设置 + +![parser](../image/config/parser.png){width=500}{class=ab-shadow-card} + +
+ +- **Enable**: 是否启用 RSS 解析器。 +- **Source** 为 RSS 解析器类型,目前支持 `mikan` 。 +- **Token** 为蜜柑计划的 Token。[蜜柑计划 Token 获取][rss_token] +- **Custom_url** 为自定义蜜柑计划地址。[自定义反代地址][reproxy] +- **Language** 为 RSS 解析器语言,目前支持 `zh` 、 `jp` 、 `en` 三种语言。 +- **Parser_type** 为 **官方标题** 解析器解析类型,支持类型如下: + - parser 为正则表达式解析器,使用正则表达式解析标题。 + - mikan 为蜜柑计划解析器,使用蜜柑计划解析标题。 + - tmdb 为 TMDB 解析器,使用 TMDB 解析标题。 +- **Exclude** 为全局 RSS 解析器过滤器,可以填入字符串或者正则表达式,AB 在解析 RSS 时会过滤掉符合过滤器的条目。 + + +## `config.json` 中的配置选项 + +在配置文件中对应选项如下: + +配置文件部分:`rss_parser` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|-------------|----------------|------|----------------|---------------| +| enable | RSS 解析器是否启用 | 布尔值 | RSS 解析器是否启用 | true | +| type | RSS 解析器类型 | 字符串 | RSS 解析器类型 | mikan | +| token | RSS 解析器 Token | 字符串 | RSS 解析器 Token | token | +| custom_url | RSS 解析器自定义 URL | 字符串 | RSS 解析器自定义 URL | mikanime.tv | +| parser_type | RSS 解析器解析类型 | 字符串 | RSS 解析器解析类型 | parser | +| filter | RSS 解析器过滤器 | 数组 | 过滤器 | [720,\d+-\d+] | +| language | RSS 解析器语言 | 字符串 | RSS 解析器语言 | zh | + + +[rss_token]: rss +[reproxy]: proxy##反向代理设置 \ No newline at end of file diff --git a/docs/config/program.md b/docs/config/program.md new file mode 100644 index 00000000..ddbc05b6 --- /dev/null +++ b/docs/config/program.md @@ -0,0 +1,27 @@ +# 主程序运行配置 + +## WebUI 配置 + +![program](../image/config/program.png){width=500}{class=ab-shadow-card} + +
+ +- Interval Time 参数的单位为秒,如果你需要设置为分钟,请自行转换为秒。 +- RSS 为 RSS 检查时间间隔,这个参数影响自动下载规则生成的周期间隔。 +- Rename 为重命名检查时间间隔,如果你需要修改重命名检查时间间隔,请修改此参数。 +- WebUI Port 为端口,请注意如果你使用 Docker 部署,修改后需要在 Docker 中重新映射端口。 + + +## `config.json` 中的配置选项 + +在配置文件中对应选项如下: + +配置文件部分:`program` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|-------------|------------|----------|------------|------| +| rss_time | RSS 检查时间间隔 | 以秒为单位的整数 | RSS 检查时间间隔 | 7200 | +| rename_time | 重命名检查时间间隔 | 以秒为单位的整数 | 重命名检查时间间隔 | 60 | +| webui_port | WebUI 端口 | 以整数为单位 | WebUI 端口 | 7892 | + + diff --git a/docs/config/proxy.md b/docs/config/proxy.md new file mode 100644 index 00000000..4ca449c1 --- /dev/null +++ b/docs/config/proxy.md @@ -0,0 +1,54 @@ +# 代理和反向代理 + +## 代理 + +![proxy](../image/config/proxy.png){width=500}{class=ab-shadow-card} + +
+ +AB 支持 HTTP 代理和 SOCKS5 代理,通过设置代理可以解决一些网络问题。 + +- **Enable**: 是否启用代理。 +- **Type** 为代理类型。 +- **Host** 为代理地址。 +- **Port** 为代理端口。 + +需要注意的是,在 HTTP 模式下不支持用户名密码验证,如果你的代理需要用户名密码验证,请使用 **SOCKS5** 模式。 + +## 反向代理设置 + +为了应对 [蜜柑计划](https://mikanani.me) 无法访问的情况,AB 增加了三种应对的方式。 + +1. HTTP 以及 Socks 代理 + + 老版本的 AB 就有这项功能,升级到 2.6 版本之后只需要在 WebUI 中检查代理配置即可正常访问蜜柑计划。 + + 不过这时候 qBittorrent 无法正常访问蜜柑计划的 RSS 和种子地址,因此需要在 qBittorrent 中添加代理。详情可以查看: [Mikan 被墙怎么办](../faq/mikan-network.md) + +2. 自定义反向代理 URL + + 2.6 版本的 AB 在配置中增加了 `custom_url` 选项,可以自定义反向代理的 URL。 + 可以在配置中设置为自己正确设置的反代 URL。这样 AB 就会使用自定义的 URL 来访问蜜柑计划。并且 QB 也可以正常下载。 + +3. AB 作为反代中转 + + 在 AB 配置代理之后,AB 自身可以作为本地的反代中转。不过目前仅开放 RSS 相关功能的反代。 + 这时候只需要把 `custom_url` 设置为 `http://abhost:abport` 即可。 `abhost` 为 AB 的 IP 地址,`abport` 为 AB 的端口。 + 此时 AB 会把自身地址推送给 qBittorrent,qBittorrent 会使用 AB 的地址作为反代来访问蜜柑计划。 + + 请注意,此时如果你没有用 NGINX 等工具对 AB 进行反代,请填入 `http://` 来保证程序正常运行。 + +## `config.json` 中的配置选项 + +在配置文件中对应选项如下: + +配置文件部分:`proxy` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|----------|--------|------|------------|-------| +| enable | 是否启用代理 | 布尔值 | 代理 | false | +| type | 代理类型 | 字符串 | 代理类型 | http | +| host | 代理地址 | 字符串 | 代理地址 | +| port | 代理端口 | 整数 | 代理端口 | +| username | 代理用户名 | 字符串 | 代理用户名 | +| password | 代理密码 | 字符串 | 代理密码 | diff --git a/docs/config/rss.md b/docs/config/rss.md new file mode 100644 index 00000000..c670bad4 --- /dev/null +++ b/docs/config/rss.md @@ -0,0 +1,40 @@ +# 准备 Mikan RSS 订阅链接 + +AutoBangumi 可以自动解析 [Mikan Project][mikan-site] 的 RSS 订阅地址,根据字幕组以及番剧名称生成下载规则, 从而实现自动追番。 +因此在开始自动追番之前,你需要准备好 [Mikan Project][mikan-site] 的 RSS 订阅地址。 + +需要注意的是,目前 Mikan Project 主站已经被墙,当你不知道如何使用代理时请使用如下链接进行访问订阅: + +[Mikan Project CN][mikan-cn-site] + +## 获取订阅地址 + +本项目基于解析 Mikan Project 提供的 RSS 地址,因此如果要实现自动追番,需要注册并且获得 Mikan Project 的 RSS 地址: + +![image](../image/rss/rss-token.png){data-zoomable} + +获取的 RSS 地址如下: + +```txt +https://mikanani.me/RSS/MyBangumi?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +# 或者 +https://mikanime.tv/RSS/MyBangumi?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` + +AB 中需要填入的 `token` 为以上 url 中 `token=` 后面的一串字符。 + +## Mikan Project 订阅贴士 + +由于 AutoBangumi 会解析所有获得的 RSS 信息,因此在订阅番剧的时候需要注意以下几点: + +![image](../image/rss/advanced-subscription.png){data-zoomable} + +- 在个人设置中打开高级设置。 +- 一部番剧只订阅一个字幕组,点击 Mikan Project 的番剧图片即可呼出二级菜单,选择一个字幕组订阅即可。 +- 如果字幕组有简体繁体不同的字幕,Mikan Project 大多时候提供了选择订阅的方式,选择一种字幕订阅。 +- 如果不提供简繁选择,那么可以在 AutoBangumi 中设置 `filter` 进行过滤,也可以在规则生成之后进入 qBittorrent 中手动过滤。 +- 目前不支持 OVA 以及 剧场版 的订阅解析。 + + +[mikan-site]: https://mikanani.me/ +[mikan-cn-site]: https://mikanime.tv/ \ No newline at end of file diff --git a/docs/deploy/docker-cli.md b/docs/deploy/docker-cli.md new file mode 100644 index 00000000..05508281 --- /dev/null +++ b/docs/deploy/docker-cli.md @@ -0,0 +1,45 @@ +# 使用 Docker-cli 部署 + +## 新版本提醒 + +AutoBangumi 2.6 版本后支持直接在 WebUI 中配置,你可以选择直接拉起容器再在 WebUI 中配置。老版本的环境变量配置参数会自动迁移,环境变量配置方式仍然可用,但是仅在第一次启动时生效。 + +## 创建数据和配置文件夹 + +为了保证 AB 在每次更新之后数据和配置不丢失,推荐使用 Docker volume 或者 bind mount 进行数据和配置的持久化。 + +```shell +# 使用 Docker volume +docker volume create AutoBangumi_config +docker volume create AutoBangumi_data + +# 使用 bind mount +mkdir "AutoBangumi" +cd "AutoBangumi" +mkdir -p $PWD/config +mkdir -p $PWD/data +``` + +## 使用 Docker-cli 部署 AutoBangumi + +复制以下命令运行即可。 + +```shell +docker run -d \ + --name=AutoBangumi \ + -v AutoBangumi_config:/app/config \ + -v AutoBangumi_data:/app/data \ + -p 7892:7892 \ + --network=bridge \ + --dns=8.8.8.8 \ + --restart unless-stopped \ + estrellaxd/auto_bangumi:latest +``` + +如果使用 bind mount,可以自行替换绑定路径。 + +此时 AB 的 WebUI 会自动运行,但是主程序会处于暂停状态,可以进入 `http://abhost:7892` 进行配置。 + +此时 AB 会自动把环境变量写入 `config.json` 文件中然后自动运行。 + +推荐使用 _[Portainer](https://www.portainer.io)_ 等带有 UI 的 Docker 管理器进行进阶部署 diff --git a/docs/deploy/docker-compose.md b/docs/deploy/docker-compose.md new file mode 100644 index 00000000..76c5c4d6 --- /dev/null +++ b/docs/deploy/docker-compose.md @@ -0,0 +1,95 @@ +# 通过 Docker Compose 部署 AutoBangumi + +现在提供了一键部署的 **AutoBangumi** 的方法,可以使用 `docker-compose.yml` 文件进行部署。 + +## 安装 Docker Compose + +正常来说安装完 Docker 之后都会自带 `docker-compose`,使用命令: + +```bash +docker compose -v +``` + +检查版本即可 + +如果没有安装,可以使用以下命令安装: + +```bash + $ sudo apt-get update + $ sudo apt-get install docker-compose-plugin +``` + +## 部署 **AutoBangumi** + +### 创建 AutoBangumi 文件夹 + +```bash +mkdir AutoBangumi +cd AutoBangumi +``` + +### 选项1: 自定义 Docker Compose 配置文件 + +```yaml +version: "3.8" + +services: + AutoBangumi: + image: estrellaxd/auto_bangumi:latest + container_name: AutoBangumi + volumes: + - ./config:/app/config + - ./data:/app/data + ports: + - "7892:7892" + restart: unless-stopped + dns: + - 223.5.5.5 + +volumes: + AutoBangumi_config: + name: AutoBangumi_config + AutoBangumi_data: + name: AutoBangumi_data +``` + +复制上面的内容到 `docker-compose.yml` 文件中。 + +### 选项2: 下载 Docker Compose 配置文件 + +当你不想自己创建 `docker-compose.yml` 文件时, +项目中提供了三种安装方式: + +- 只安装 **AutoBangumi** + ```bash + wget https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/main/docs/docker-compose/AutoBangumi/docker-compose.yml + ``` +- 安装 **qBittorrent** 与 **AutoBangumi** + ```bash + wget https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/main/docs/docker-compose/qBittorrent+AutoBangumi/docker-compose.yml + ``` +- **qBittorrent** + **AutoBangumi** + **Plex** + ```bash + wget https://raw.githubusercontent.com/EstrellaXD/Auto_Bangumi/main/docs/docker-compose/All-in-one/docker-compose.yml + ``` + +首先选择你要安装的方式,**拷贝上面的命令运行即可**,这一步是下载 `docker-compose.yml` 配置文件,如果需要自定义可以使用文本编辑器对其中的参数进行自定义。 + +### 定义环境变量 + +如果你是用上面下载的 AB+QB / AB+QB+Plex 的 Docker-Compose 文件,那么你需要定义以下环境变量: + +```shell +export \ +QB_PORT= +``` + +- `QB_PORT`: 填写你的已经部署的 qBittorrent 端口号,或者想要自定义的端口号,比如: `8080` + +### 拉起 Docker-Compose + +```bash +# 如果配置过了上面的环境变量,请使用下面的方式拉起 +docker compose up -d +``` + diff --git a/docs/deploy/dsm.md b/docs/deploy/dsm.md new file mode 100644 index 00000000..1c075a18 --- /dev/null +++ b/docs/deploy/dsm.md @@ -0,0 +1,123 @@ +# 群晖 (DSM 7.2) 部署说明( QNAP 同理) + +在 DSM 7.2 中,已经支持了 Docker Compose,推荐使用 Docker Compose 一键部署本项目。 + +## 创建配置和数据存储文件夹 + +‼️在 `/volume1/docker/` 下创建 `ab` 文件夹,然后在 `ab` 文件夹下创建 `config` 和 `data` 文件夹。 + +## 安装 Container Manager (Docker) 套件 + +进入套件中心,安装 Container Manager (Docker) 套件。 + +![install-docker](../image/dsm/install-docker.png){data-zoomable} + +## 通过 Docker compose 安装配置 AB + +点击 **项目**,然后点击 **新建**,选择 **Docker Compose**。 + +![new-compose](../image/dsm/new-compose.png){data-zoomable} + +复制以下内容填入 **Docker Compose** 中。 +```yaml +version: "3.8" + +services: + ab: + image: "ghcr.io/estrellaxd/auto_bangumi:latest" + container_name: "auto_bangumi" + restart: unless-stopped + ports: + - "7892:7892" + volumes: + - "/volume1/docker/ab/config:/app/config" + - "/volume1/docker/ab/data:/app/data" +``` + +点击 **下一步**,然后点击 **完成**。 + +![create](../image/dsm/create.png){data-zoomable} + +完成创建之后进入 `http://:7892` 即可进入 AB 并进行配置。 + +## 通过 Docker compose 安装配置 AB 和 qBittorrent + +在同时拥有代理和ipv6的情况下,群晖nas提供的docker配置ipv6极为复杂,推荐直接将AB和qBittorrent安装到host网络下,降低工作量。 + +以下内容的使用条件为:在docker上已经部署好了一个clash代理,并能够通过本地ip的指定端口进行访问。 + +参考上一节的内容,将以下内容经过调整填入 **Docker Compose** 中。 + +```yaml +version: "3.2" +services: + qbittorrent: + container_name: qBittorrent + environment: + - TZ=Asia/Shanghai + - TemPath=/downloads + - SavePath=/downloads + - PGID=1000 #需要自行修改填入 + - PUID=1000 #需要自行修改填入 + - WEBUI_PORT=8080 #建议自行修改端口号 + volumes: + - /volume1/docker/qb/config:/config + - /volume1/docker/qb/downloads:/downloads # 填入下载路径 + ports: + - 8080:8080 # 建议自行修改端口号 + - "6881:6881" + - "6881:6881/udp" + network_mode: + host + restart: unless-stopped + image: superng6/qbittorrent + + auto_bangumi: + container_name: AutoBangumi + environment: + - TZ=Asia/Shanghai + - PGID=1000 #需要自行修改填入 + - PUID=1000 #需要自行修改填入 + - AB_DOWNLOADER_HOST=127.0.0.1:8080 #建议自行修改端口号 + volumes: + - /volume1/docker/ab/config:/app/config + - /volume1/docker/ab/data:/app/data + network_mode: + host + ports: + - '7892:7892' + dns: + - 8.8.8.8 + - 223.5.5.5 + restart: unless-stopped + image: estrellaxd/auto_bangumi:latest + depends_on: + - qbittorrent + +``` + +## 补充说明 + +其中的 PGID 与 PUID 需要自行寻找,群晖的新 NAS 通常应该是:`PUID=1026,PGID=100`,qBittorrent 对应的端口号在修改时注意保证所有位置全部修改完成。 + +如果需要设置代理,请参考: [设置代理](../config/proxy) + +如果使用较低性能的机器,默认的配置有概率会大量占用 **CPU**,使得 AB 无法链接 qB 且 qB 的 WebUI 无法正常登陆的情况。 + +以 220+ 为例,qB 参考配置如下,减少下载与上传的连接数,降低 CPU 占用。 + +- 设置 -> 链接 -> 链接限制 + - 全局最大连接数: 300 + - 每torrent最大连接数: 60 + - 全局上传窗口数上限: 15 + - 每个torrent上传窗口数上限: 4 +- BitTorrent + - 最大活跃检查种子数 1 + - Torrent排队 + - 最大活动的下载数: 3 + - 最大活动的上传数: 5 + - 最大活动的torrent数: 10 +- RSS +- RSS阅读器 + - 每个订阅源文章数目最大值: 50 + diff --git a/docs/deploy/quick-start.md b/docs/deploy/quick-start.md new file mode 100644 index 00000000..03f70a6d --- /dev/null +++ b/docs/deploy/quick-start.md @@ -0,0 +1,113 @@ +# 快速开始 + +我们推荐你在 Docker 中部署运行 AutoBangumi。 +部署前请确认已经安装了 [Docker Engine][docker-engine] 或者 [Docker Desktop][docker-desktop]。 + +## 创建数据和配置文件夹 + +为了保证 AB 在每次更新之后数据和配置不丢失,推荐使用 Docker volume 进行数据和配置的持久化。 + +```shell +docker volume create AutoBangumi_config +docker volume create AutoBangumi_data +``` +## 使用 Docker 部署 AutoBangumi + +### 选项1: 使用 Docker-cli 部署 + +复制以下命令运行即可。 + +```shell +docker run -d \ + --name=AutoBangumi \ + -v AutoBangumi_config:/app/config \ + -v AutoBangumi_data:/app/data \ + -p 7892:7892 \ + --network=bridge \ + --dns=8.8.8.8 \ + --restart unless-stopped \ + estrellaxd/auto_bangumi:latest + +``` + +### 选项2: 使用 Docker-compose 部署 + +复制以下内容到 `docker-compose.yml` 文件中。 + +```yaml +version: "3.8" + +services: + AutoBangumi: + image: estrellaxd/auto_bangumi:latest + container_name: AutoBangumi + volumes: + - AutoBangumi_config:/app/config + - AutoBangumi_data:/app/data + ports: + - 7892:7892 + restart: unless-stopped + dns: + - 223.5.5.5 + network_mode: bridge + +volumes: + AutoBangumi_config: + name: AutoBangumi_config + AutoBangumi_data: + name: AutoBangumi_data +``` + +运行以下命令启动容器。 + +```shell +docker compose up -d +``` + +## 安装 qBittorrent + +如果你没有安装 qBittorrent,请先安装 qBittorrent。 + +- [在 Docker 中安装 qBittorrent][qbittorrent-docker] +- [在 Windows/macOS 中安装 qBittorrent][qbittorrent-desktop] +- [在 Linux 中安装 qBittorrent-nox][qbittorrent-nox] + +## 获取 Mikan Project 的 RSS 链接 + +进入 [MiKan Project][mikan-project],注册账号并登录,然后点击右下角的 **RSS** 按钮,复制链接。 + +![mikan-rss](../image/rss/rss-token.png){data-zoomable} + +获取的 RSS 地址如下: + +```txt +https://mikanani.me/RSS/MyBangumi?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +# 或者 +https://mikanime.tv/RSS/MyBangumi?token=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +``` +复制 token= 后面的内容。 + +详细步骤参考 [Mikan RSS][config-rss] + + +## 配置 AutoBangumi + +安装好 AB 之后,AB 的 WebUI 会自动运行,但是主程序会处于暂停状态,可以进入 `http://abhost:7892` 进行配置。 + +1. 填入下载器的地址,端口,用户名和密码。 + +![ab-webui](../image/config/downloader.png){width=500}{class=ab-shadow-card} + +2. 填入 Mikan RSS 的 Token。 + +![ab-rss](../image/config/parser.png){width=500}{class=ab-shadow-card} + +3. 点击 **Apply** 保存配置,此时 AB 会重启运行,当右上角的圆点变为绿色时,表示 AB 已经正常运行。 + +[docker-engine]: https://docs.docker.com/engine/install/ +[docker-desktop]: https://www.docker.com/products/docker-desktop +[config-rss]: ../config/rss +[mikan-project]: https://mikanani.me/ +[qbittorrent-docker]: https://hub.docker.com/r/superng6/qbittorrent +[qbittorrent-desktop]: https://www.qbittorrent.org/download +[qbittorrent-nox]: https://www.qbittorrent.org/download-nox \ No newline at end of file diff --git a/docs/deploy/unix.md b/docs/deploy/unix.md new file mode 100644 index 00000000..bf662726 --- /dev/null +++ b/docs/deploy/unix.md @@ -0,0 +1,41 @@ +# 如何在本地运行 AutoBangumi + +## 克隆项目 + +```bash +git clone https://github.com/EstrellaXD/Auto_Bangumi.git +``` + +## 安装依赖 +确认你的电脑本地已经安装了 `python3.10` 以上的版本,以及 `pip` 包管理工具。 + +```bash +python3 pip install -r requirements.txt +``` + +## 进入源代码目录并且创建版本信息 + +```bash +cd backend/src + +echo "VERSION = 'local'" > module/__version__.py +``` + +## 下载 WebUI + +```bash +wget https://github.com/Rewrite0/Auto_Bangumi_WebUI/releases/download/latest/dist.zip + +unzip dist.zip + +mv dist templates +``` + +## 创建配置文件夹以及数据文件夹并运行 + +```bash +mkdir "config" +mkdir "data" + +python3 main.py +``` diff --git a/docs/deploy/windows.md b/docs/deploy/windows.md new file mode 100644 index 00000000..632c1abb --- /dev/null +++ b/docs/deploy/windows.md @@ -0,0 +1,178 @@ +# Windows 本地部署 + + +1. 克隆并进入 AutoBangumi 的 `git` 仓库: + + ```powershell + git clone https://github.com/EstrellaXD/Auto_Bangumi.git + cd Auto_Bangumi + ``` + +2. 创建版本信息文件: + + ```powershell + echo "VERSION='local'" > backend\src\module\__version__.py + ``` + +3. 新建 `python` 虚拟环境、激活并安装依赖(需保证 `python -V` 打印的版本符合 `Dockerfile` 中的要求,如 `FROM python:3.11-alpine AS APP`) + + ```powershell + python -m venv env + .\env\Scripts\Activate.ps1 + python -m pip install -r backend\requirements.txt + ``` + +4. 下载 WebUI 并安装: + + ```powershell + Invoke-WebRequest -Uri "https://github.com/Rewrite0/Auto_Bangumi_WebUI/releases/latest/download/dist.zip" -OutFile "dist.zip" + Expand-Archive -Path "dist.zip" + mv dist\* backend\src\templates + ``` + +5. 创建 `data` 与 `config` 目录和空白的 `config_dev.json`(如果有必要将这些目录存储在其他位置,建议使用 Junction Directory 链接即可) + + ```powershell + mkdir backend\src\data + mkdir backend\src\config + echo "{}" > backend\src\config\config_dev.json + ``` + 默认情况下,PowerShell 输出文件编码为 `UTF-16LE`,你需要将 `config_dev.json` 的编码格式改为 `UTF-8`。 + +6. 运行程序测试是否配置正确: + + ```powershell + cd backend\src + python main.py + ``` + +7. 接下来配置成服务以实现开机自启,以下以 `nssm` 为例: + + ```powershell + nssm install AutoBangumi (Get-Command python).Source + nssm set AutoBangumi AppParameters (Get-Item .\main.py).FullName + nssm set AutoBangumi AppDirectory (Get-Item ..).FullName + nssm set AutoBangumi Start SERVICE_DELAYED_AUTO_START + ``` + +8. [可选] 由于 3.0 版本之前 AutoBangumi 没有修改规则或者批量移动下载位置的功能,可能遇到季名不符合需要 (如《鬼灭之刃 刀匠村篇》被视作一个仅具有一季的独立的影视作品,而不是系列动画的第三季) 或者中途想继续下载但是移出库防止出现在新剧集通知中等情况,可与考虑将下载目录和库目录区分开并用 Junction Directory 相连,这样在管理库时可以随意移动软链接而不影响 AutoBangumi 的工作。比如: + ```powershell + ### Configurations + $downloadDir = "path\to\download_dir" + $libraryDir = "path\to\library_dir" + $logFile = $(Join-Path -Path $download_dir -ChildPath "downloadWatcher.log") + $subfolderCreationTimeout = 10 + $watcher = New-Object System.IO.FileSystemWatcher + $watcher.Path = $downloadDir + $watcher.EnableRaisingEvents = $true + + function CreateJunction( + # The path to the folder containing junction targets, e.g. $downloadDir\ + # The junction targets are its subfolders e.g. $downloadDir\\ + $targetRoot + ) { + # The basename of $targetRoot, e.g. + $targetRootName = Split-Path -Path $targetRoot -Leaf + # The path the folder where junctions are created, e.g. $libraryDir\ + $junctionRoot = $(Join-Path -Path $libraryDir -ChildPath $targetRootName) + # Create $junctionRoot if it does not exist + if (!(Test-Path $junctionRoot)) { + New-Item -ItemType Directory -Path $junctionRoot + Add-Content $logFile -Value "[Information] $(Get-Date) New folder created at $junctionRoot mirroring $targetRoot." + } + # Wait up to 10 secs for a subfolder to appear in $targetRoot + # This is because if $targetRoot is newly created the downloader may not have created the subfolder yet + $junctionTargetList = $(Get-ChildItem -Path $targetRoot -Directory) + $subfolderWaitCount = 0 + while ($junctionTargetList.Count -eq 0) { + if ($subfolderWaitCount -ge $subfolderCreationTimeout) { + Add-Content $logFile -Value "[Warning] $(Get-Date) No subfolders exist in $targetRoot for junctioning, skipping." + Return + } + Start-Sleep -Seconds 1 + try { + $junctionTargetList = $(Get-ChildItem -Path $targetRoot -Directory) + } + # If $targetRoot is removed/renamed during the wait, skip + catch [System.IO.DirectoryNotFoundException] { + Add-Content $logFile -Value "[Warning] $(Get-Date) $targetRoot is removed/renamed during the wait, skipping." + Return + } + $subfolderWaitCount++ + } + Get-ChildItem $junctionRoot | Where-Object {$_.LinkType -eq "Junction"} | ForEach-Object { + # If a junction target is non-existent, remove it + if (!(Test-Path $_.Target)) { + Remove-Item $_.FullName + Add-Content $logFile -Value "[Information] $(Get-Date) Junction at $($_.FullName) is removed because its target $($_.Target) is non-existent." + } + else { + # Remove a junction target from $junctionTargetList if a junction in $junctionRoot is already pointing to it + $existingTarget = $_.Target + $junctionTargetList = $junctionTargetList | Where-Object {$_.FullName -ne $existingTarget} + Add-Content $logFile -Value "[Debug] $(Get-Date) $($_.FullName) already exists, skipping." + } + } + # Create junctions for each remaining target in $junctionTargetList + for ($i = 0; $i -lt $junctionTargetList.Count; $i++) { + $junctionTarget = $junctionTargetList[$i] + # The default name for the junction is the name of the junction target it self, e.g. + $junctionName = $junctionTarget.Name + # If a junction with the same name already exists, append the current date to the name, e.g. -yyyy-MM-dd + if (Test-Path $(Join-Path -Path $junctionRoot -ChildPath $junctionName)) { + $junctionName = "$junctionName-$(Get-Date -Format "yyyy-MM-dd")" + # If the new name is still taken, append a random string generated by taking first 5 chars from New-Guid to the name, e.g. -yyyy-MM-dd- + while (Test-Path $(Join-Path -Path $junctionRoot -ChildPath $junctionName)) { + $junctionName = "$junctionName-$((New-Guid).ToString().Substring(0, 5))" + } + } + # Create the junction + New-Item -ItemType Junction -Path $(Join-Path -Path $junctionRoot -ChildPath $junctionName) -Value $junctionTarget.FullName + Add-Content $logFile -Value "[Information] $(Get-Date) New junction created at $(Join-Path -Path $junctionRoot -ChildPath $junctionName) pointing to $junctionTarget." + } + } + + $action = { + # Event arguments, see https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemeventargs + $details = $event.SourceEventArgs + $path = $details.FullPath # Gets the full path of the affected file or directory. + $changeType = $details.ChangeType # Gets the change type, e.g. Created, Deleted, Renamed + Add-Content $logFile -Value "[Debug] $(Get-Date) $changeType event detected at $path." + if (!(Test-Path $path -PathType Container)) { + Add-Content $logFile -Value "[Debug] $(Get-Date) $name is not mirrored because it is not a folder." + Return + } + # If the directory contains .nomirror file, skip + if (Test-Path $(Join-Path -Path $path -ChildPath ".nomirror")) { + Add-Content $logFile -Value "[Debug] $(Get-Date) $path is not mirrored because it contains .nomirror file." + Return + } + # Process the directory as a root of junction targets + $targetRoot = $path + # If the directory is renamed, rename its mirror directory + if ($changeType -eq [System.IO.WatcherChangeTypes]::Renamed) { + $oldJunctionRoot = $(Join-Path -Path $libraryDir -ChildPath $details.OldName) + $newJunctionRoot = $(Join-Path -Path $libraryDir -ChildPath $details.Name) + if (Test-Path $oldJunctionRoot) { + Rename-Item -Path $oldJunctionRoot -NewName $details.Name + Add-Content $logFile -Value "[Information] $(Get-Date) $oldJunctionRoot is renamed to $newJunctionRoot." + } + else { + Add-Content $logFile -Value "[Warning] $(Get-Date) Junction at $oldJunctionRoot does not exist, skipping." + } + } + # If a directory is modified or newly created, update/create its mirror directory by creating/updating junctions to point to its subfolders + if ($changeType -eq [System.IO.WatcherChangeTypes]::Changed -or ` + $changeType -eq [System.IO.WatcherChangeTypes]::Renamed -or ` + $changeType -eq [System.IO.WatcherChangeTypes]::Created) { + CreateJunction $targetRoot + } + } + + Register-ObjectEvent -InputObject $watcher -EventName Created -Action $action + Register-ObjectEvent -InputObject $watcher -EventName Changed -Action $action + Register-ObjectEvent -InputObject $watcher -EventName Renamed -Action $action + while ($true) {Start-Sleep 5} + ``` + 上述脚本定义了一个 FileSystemWatcher 来监控下载目录的变化并镜像到库目录,可以用 `nssm` 安装为服务自动运行。如果需要排除一个目录,则只需要在该目录下新建一个名为 `.nomirror` 的文件即可。 + diff --git a/docs/deploy/wsl.md b/docs/deploy/wsl.md new file mode 100644 index 00000000..38bc327c --- /dev/null +++ b/docs/deploy/wsl.md @@ -0,0 +1,61 @@ +# WSL 配置说明 + +感谢 #73 的贡献 + +WSL 用户可以用以下 `docker-compose.yml` 配置文件来部署 AutoBangumi + +```yml +version: "3.6" +services: + qbittorrent: + container_name: qbittorrent + image: johngong/qbittorrent:latest + hostname: qbittorrent + environment: + - QB_EE_BIN=false + - UID=1000 # 用户权限1000 当前WSL登录用户,查询方法 wsl内输入 id 用户名 + - GID=1000 + - QB_WEBUI_PORT=8989 + ports: + - "6881:6881" + - "6881:6881/udp" + - "8989:8989" + volumes: + - qb_config:/config + - /mnt/g/animation:/Downloads #下载路径,对应 Windows上目录是 G:\animation + networks: + - AutoBangumi_network + restart: unless-stopped + + AutoBangumi: + image: estrellaxd/auto_bangumi:latest + container_name: AutoBangumi + ports: + - 7892:7892 + depends_on: + - qbittorrent + volumes: + - ./config:/app/config + - ./data:/app/data + environment: + - PUID=1000 + - PGID=1000 + - TZ=Asia/Shanghai + - AB_DOWNLOADER_HOST=qbittorrent:8989 + - AB_DOWNLOADER_USERNAME=admin + - AB_DOWNLOADER_PASSWORD=adminadmin + - AB_NOT_CONTAIN=720|繁体|CHT|JPTC|繁日|BIG5 + - AB_DOWNLOAD_PATH=/Downloads #qbittorrent 映射的地址,否者可能提示下载失败 + - AB_RSS=https://mikanani.me/RSS/MyBangumi?token=xxxxxxxx%3d%3d #订阅地址,改成自己的 + networks: + - AutoBangumi_network + restart: unless-stopped + +networks: + AutoBangumi_network: +volumes: + qb_config: + external: false + auto_bangumi: + external: false +``` \ No newline at end of file diff --git a/docs/dev/index.md b/docs/dev/index.md new file mode 100644 index 00000000..9573c71d --- /dev/null +++ b/docs/dev/index.md @@ -0,0 +1,138 @@ +# 贡献指南 Contributing + +我们欢迎各位 Contributors 参与贡献帮助 AutoBangumi 更好的解决大家遇到的问题, + +这篇指南会指导你如何为 AutoBangumi 贡献功能修复代码,可以在你要提出 Pull Request 之前花几分钟来阅读一遍这篇指南。 + +这篇文章包含什么? + +- [项目规划 Roadmap](#项目规划-roadmap) + - [提案寻求共识 Request for Comments](#提案寻求共识-request-for-comments) +- [分支管理 Git Branch](#分支管理-git-branch) + - [版本号](#版本号) + - [分支开发,主干发布](#分支开发主干发布) + - [Branch 生命周期](#branch-生命周期) + - [Git Workflow 一览](#git-workflow-一览) +- [Pull Request](#pull-request) +- [版本发布介绍](#版本发布介绍) + + +## 项目规划 Roadmap + +AutoBangumi 开发组使用 [GitHub Project](https://github.com/EstrellaXD/Auto_Bangumi/projects?query=is%3Aopen) 看板来管理预计开发的规划、在修复中的问题,以及它们处理的进度; + +这将帮助你更好的了解 +- 开发团队在做什么? +- 有什么和你想贡献的方向一致的,可以直接参与实现与优化 +- 有什么已经在进行中的,避免自己重复不必要的工作 + +在 [Project](https://github.com/EstrellaXD/Auto_Bangumi/projects?query=is%3Aopen) 中你可以看到除通常的 `[Feature Request]`, `[BUG]`, 一些小优化项以外,还有一类 **`[RFC]`**; + +### 提案寻求共识 Request for Comments + +> 在 issue 中通过 `RFC` label 能找到到现有的 [AutoBangumi RFCs](https://github.com/EstrellaXD/Auto_Bangumi/issues?q=is%3Aissue+label%3ARFC) + +对于一些小的优化项或者 bug 修复,你大可以直接帮忙调整代码然后提出 Pull Request,只需要简单阅读下 [分支管理](#分支管理-Git-Branch) 章节以基于正确的版本分支修复、以及通过 [Pull Request](#Pull-Request) 章节了解 PR 将如何被合并。 + +
+ +而如果你打算做的是一项**较大的**功能重构,改动范围大而涉及的方面比较多,那么希望你能通过 [Issue: 功能提案](https://github.com/EstrellaXD/Auto_Bangumi/issues/new?assignees=&labels=RFC&projects=&template=rfc.yml&title=%5BRFC%5D%3A+) 先写一份 RFC 提案来简单阐述「你打算怎么做」的简短方案,来寻求开发者的讨论和共识。 + +因为有些方案可能是开发团队原本讨论并且认为不要做的事,而上一步可以避免你浪费大量精力。 + +> 如果仅希望讨论是否添加或改进某功能本身,而非「要如何实现」,请使用 -> [Issue: 功能改进](https://github.com/EstrellaXD/Auto_Bangumi/issues/new?labels=feature+request&template=feature_request.yml&title=%5BFeature+Request%5D+) + + +
+ +一份 [提案(RFC)](https://github.com/EstrellaXD/Auto_Bangumi/issues?q=is%3Aissue+is%3Aopen+label%3ARFC) 定位为 **「在某功能/重构的具体开发前,用于开发者间 review 技术设计/方案的文档」**, + +目的是让协作的开发者间清晰的知道「要做什么」和「具体会怎么做」,以及所有的开发者都能公开透明的参与讨论; + +以便评估和讨论产生的影响 (遗漏的考虑、向后兼容性、与现有功能的冲突), + +因此提案侧重在对解决问题的 **方案、设计、步骤** 的描述上。 + + +## 分支管理 Git Branch + +### 版本号 + +AutoBangumi 项目中的 Git 分支使用与发布版本规则密切相关,因此先介绍版本规范; + +AutoBangumi 发布的版本号遵循 [「语义化版本 SemVer」](https://semver.org/lang/zh-CN/) 的规范, + +使用 `..` 三位版本的格式,每一位版本上的数字更新含义如下: + +- **Major**: 大版本更新,很可能有不兼容的 配置/API 修改 +- **Minor**: 向下兼容的功能性新增 +- **Patch**: 向下兼容的 Bug 修复 / 小优化修正 + +### 分支开发,主干发布 + +AutoBangumi 项目使用「分支开发,主干发布」的模式, + +[**`main`**](https://github.com/EstrellaXD/Auto_Bangumi/commits/main) 分支是稳定版本的 **「主干分支」**,只用于发布版本,不用于直接开发新功能或修复。 + +每一个 Minor 版本都有一个对应的 **「开发分支」** 用于开发新功能、与发布后维护修复问题, + +开发分支的名字为 `.-dev`,如 `3.1-dev`, `3.0-dev`, `2.6-dev`, 你可以在仓库的 [All Branches 中搜索到它们](https://github.com/EstrellaXD/Auto_Bangumi/branches/all?query=-dev)。 + + +### Branch 生命周期 + +当一个 Minor 开发分支(以 `3.1-dev` 为例) 完成新功能开发,**首次**合入 main 分支后, +- 发布 Minor 版本 (如 `3.1.0`) +- 同时拉出**下一个** Minor 开发分支(`3.2-dev`),用于下一个版本新功能开发 + - 而**上一个**版本开发分支(`3.0-dev`)进入归档不再维护 +- 且这个 Minor 分支(`3.1-dev`)进入维护阶段,不再增加新功能/重构,只维护 Bugs 修复 + - Bug 修复到维护阶段的 Minor 分支(`3.1-dev`)后,会再往 main 分支合并,并发布 `Patch` 版本 + +根据这个流程,对于各位 Contributors 在开发贡献时选择 Git Branch 来说,则是: +- 若「修复 Bug」,则基于**当前发布版本**的 Minor 分支开发修复,并 PR 到这个分支 +- 若「添加新功能/重构」,则基于**还未发布的下一个版本** Minor 分支开发,并 PR 到这个分支 + +> 「当前发布版本」为 [[Releases 页面]](https://github.com/EstrellaXD/Auto_Bangumi/releases) 最新版本,这也与 [[GitHub Container Registry]](https://github.com/EstrellaXD/Auto_Bangumi/pkgs/container/auto_bangumi) 中最新版本相同 + + +### Git Workflow 一览 + +> 图中 commit timeline 从左到右 ---> + +![dev-branch](../image/dev/branch.png) + + +## Pull Request + +请确保你根据上文的 Git 分支管理 章节选择了正确的 PR 目标分支, +> - 若「修复 Bug」,则 PR 到**当前发布版本**的 Minor 维护分支 +> - 若「添加新功能/重构」,则 PR **下一个版本** Minor 开发分支 + +
+ +- 一个 PR 应该只对应一件事,而不应引入不相关的更改; + + 对于不同的事情可以拆分提多个 PR,这能帮助开发组每次 review 只专注一个问题。 + +- 在提 PR 的标题与描述中,最好对修改内容做简短的说明,包括原因和意图, + + 如果有相关的 issue 或 RFC,应该把它们链接到 PR 描述中, + + 这将帮助开发组 code review 时能最快了解上下文。 + +- 确保勾选了「允许维护者编辑」(`Allow edits from maintainers`) 选项。这使我们可以直接进行较小的编辑/重构并节省大量时间。 + +- 请确保本地通过了「单元测试」和「代码风格 Lint」,这也会在 PR 的 GitHub CI 上检查 + - 对于 bug fix 和新功能,通常开发组也会请求你添加对应改动的单元测试覆盖 + + +开发组会在有时间的最快阶段 Review 贡献者提的 PR 并讨论或批准合并(Approve Merge)。 + +## 版本发布介绍 + +版本发布目前由开发组通过手动合并「特定发版 PR」后自动触发打包与发布。 + +通常 Bug 修复的 PR 合并后会很快发版,通常不到一周; + +而新功能的发版时间则会更长而且不定,你可以在我们的 [GitHub Project](https://github.com/EstrellaXD/Auto_Bangumi/projects?query=is%3Aopen) 看板中看到开发进度,一个版本规划的新功能都开发完备后就会发版。 + diff --git a/docs/docker-compose/All-in-one/docker-compose.yml b/docs/docker-compose/All-in-one/docker-compose.yml deleted file mode 100644 index e99402a2..00000000 --- a/docs/docker-compose/All-in-one/docker-compose.yml +++ /dev/null @@ -1,71 +0,0 @@ -version: "3.2" -services: - qbittorrent: - container_name: qBittorrent - environment: - - TZ=Asia/Shanghai - - TemPath=/downloads - - SavePath=/downloads - - PGID=${GID} - - PUID=${UID} - - WEBUI_PORT=${QB_PORT} - volumes: - - qb_config:/config - - ${DOWNLOAD_PATH}:/downloads - ports: - - ${QB_PORT}:${QB_PORT} - - 6881:6881 - - 6881:6881/udp - networks: - - auto_bangumi - restart: unless-stopped - image: superng6/qbittorrent:latest - - auto_bangumi: - container_name: AutoBangumi - environment: - - TZ=Asia/Shanghai - - PGID=${GID} - - PUID=${UID} - - AB_DOWNLOADER_HOST=qbittorrent:${QB_PORT} - networks: - - auto_bangumi - volumes: - - /path/to/config:/app/config - - /path/to/data:/app/data - ports: - - 7892:7892 - dns: - - 8.8.8.8 - - 223.5.5.5 - restart: unless-stopped - image: estrellaxd/auto_bangumi:latest - depends_on: - - qbittorrent - - plex: - container_name: Plex - environment: - - TZ=Asia/Shanghai - - PUID=${UID} - - PGID=${GID} - - VERSION=docker - networks: - - auto_bangumi - ports: - - 32400:32400 - volumes: - - plex_config:/config - - ${DOWNLOAD_PATH}/Bangumi:/tv - restart: unless-stopped - image: lscr.io/linuxserver/plex:latest - -networks: - auto_bangumi: - -volumes: - qb_config: - external: false - plex_config: - external: false - diff --git a/docs/docker-compose/AutoBangumi/docker-compose.yml b/docs/docker-compose/AutoBangumi/docker-compose.yml deleted file mode 100644 index 07487d6d..00000000 --- a/docs/docker-compose/AutoBangumi/docker-compose.yml +++ /dev/null @@ -1,26 +0,0 @@ -version: '3.2' -services: - auto_bangumi: - container_name: AutoBangumi - environment: - - TZ=Asia/Shanghai - - PGID=${GID} - - PUID=${UID} - networks: - - auto_bangumi - ports: - - '7892:7892' - volumes: - - ./config:/app/config - - ./data:/app/data - dns: - - 8.8.8.8 - - 223.5.5.5 - restart: unless-stopped - image: estrellaxd/auto_bangumi:latest - -networks: - auto_bangumi: -volumes: - auto_bangumi: - external: false diff --git a/docs/docker-compose/qBittorrent+AutoBangumi/docker-compose.yml b/docs/docker-compose/qBittorrent+AutoBangumi/docker-compose.yml deleted file mode 100644 index 992c5e1d..00000000 --- a/docs/docker-compose/qBittorrent+AutoBangumi/docker-compose.yml +++ /dev/null @@ -1,50 +0,0 @@ -version: "3.2" -services: - qbittorrent: - container_name: qBittorrent - environment: - - TZ=Asia/Shanghai - - TemPath=/downloads - - SavePath=/downloads - - PGID=${GID} - - PUID=${UID} - - WEBUI_PORT=${QB_PORT} - volumes: - - qb_config:/config - - ${DOWNLOAD_PATH}:/downloads # 填入下载绝对路径 - ports: - - ${QB_PORT}:${QB_PORT} - - "6881:6881" - - "6881:6881/udp" - networks: - - auto_bangumi - restart: unless-stopped - image: superng6/qbittorrent - - auto_bangumi: - container_name: AutoBangumi - environment: - - TZ=Asia/Shanghai - - PGID=${GID} - - PUID=${UID} - - AB_DOWNLOADER_HOST=qbittorrent:${QB_PORT} - volumes: - - ./config:/app/config - - ./data:/app/data - networks: - - auto_bangumi - ports: - - '7892:7892' - dns: - - 8.8.8.8 - - 223.5.5.5 - restart: unless-stopped - image: estrellaxd/auto_bangumi:latest - depends_on: - - qbittorrent - -networks: - auto_bangumi: -volumes: - qb_config: - external: false diff --git a/docs/faq/mikan-network.md b/docs/faq/mikan-network.md new file mode 100644 index 00000000..a77baea8 --- /dev/null +++ b/docs/faq/mikan-network.md @@ -0,0 +1,75 @@ +# Mikan 网络问题的应对方法 + +由于蜜柑计划本站: `https://mikanani.me` 目前被 GFW 封锁,因此可能会导致 AB 无法正确连接蜜柑计划的情况,建议使用如下方法解决。 + +- [使用蜜柑计划国内域名](#蜜柑计划国内域名) +- [使用代理](#代理) +- [使用 CloudFlare Worker 进行反代](#cloudflare-workers) + +## 蜜柑计划国内域名 + +- 蜜柑计划更新了新的域名 `https://mikanime.tv`,请在不打开代理的情况下配合 AB 使用。 + + +## 配置代理 + +1. AB 中自带了代理配置,如果要配置代理请按照 [配置代理](../config/proxy) 中的方式正确配置 HTTP 或者 Socks 代理。配置完成可以规避墙的问题。 +2. QB 中也需要配置代理,请按照如下截图对 QB 中进行代理设置 (Socks 同理) +image + +3. 在 2.6 版本更新中 AB 额外提供了两种解决被墙的方案。 + +- 可以在 WebUI 中的 `源站链接` 中修改为自己反代过的 URL +- 使用代理之后可以使用 AB 自身作为反代节点。 + +具体可以看[配置代理](../config/proxy)中的说明。 + +## CloudFlare Workers + +根据 OpenAI 被墙的经验,我们也可以通过反向代理的方式解决。具体如何申请域名绑定 CloudFlare 在此不再赘述。 +在 Workers 中添加如下代码即可以用你自己的域名访问蜜柑计划并且解析下载 RSS 链接中的种子。 + +```javascript +const TELEGRAPH_URL = 'https://mikanani.me'; +const MY_DOMAIN = 'https://yourdomain.com' + +addEventListener('fetch', event => { + event.respondWith(handleRequest(event.request)) +}) + +async function handleRequest(request) { + const url = new URL(request.url); + url.host = TELEGRAPH_URL.replace(/^https?:\/\//, ''); + + const modifiedRequest = new Request(url.toString(), { + headers: request.headers, + method: request.method, + body: request.body, + redirect: 'manual' + }); + + const response = await fetch(modifiedRequest); + const contentType = response.headers.get('Content-Type') || ''; + + // 如果内容类型是 RSS,才进行替换操作 + if (contentType.includes('application/xml')) { + const text = await response.text(); + const replacedText = text.replace(/https?:\/\/mikanani\.me/g, MY_DOMAIN); + const modifiedResponse = new Response(replacedText, response); + + // 添加允许跨域访问的响应头 + modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); + + return modifiedResponse; + } else { + const modifiedResponse = new Response(response.body, response); + + // 添加允许跨域访问的响应头 + modifiedResponse.headers.set('Access-Control-Allow-Origin', '*'); + + return modifiedResponse; + } +} +``` + +完成上述配置之后,将你的域名填入 AB 的 **源站链接|Custom URL** 中即可。 \ No newline at end of file diff --git a/docs/faq/常见问题.md b/docs/faq/常见问题.md new file mode 100644 index 00000000..d2c28cdd --- /dev/null +++ b/docs/faq/常见问题.md @@ -0,0 +1,195 @@ +# 常见问题 + +## WebUI + +### WebUI 地址 + +默认端口为 7892,请访问 `http://serverhost:7892`,如果你修改了端口,请记得同时更改 Docker 中的端口映射。 + +### 默认用户名和密码 + +- 默认用户名:`admin`,默认密码:`adminadmin`。 +- 请务必在第一次登录后修改密码。 + +### 修改和忘记密码 + +- 修改密码:在登录后点击右上角`···`,点击 `Profile`,修改用户名和密码。 +- 目前没有简单的忘记密码的重置方法,如果忘记密码,可以删除 `data/data.db` 文件,然后重启。 + +### 为什么我修改了配置,但是没有生效? + +- 修改配置之后请点击 **Apply** 按钮,然后`···` 中的 **Restart** 按钮,此时会重启主进程。 +- 如果开启 **Debug** 模式,请点击 `···` 中的 **Shutdown**,此时会重启容器。 + +### 如何判断程序是否正常运行 + +新版 WebUI 右上角有一个小圆点,绿色表示正常运行,红色表示出现错误,程序暂停。 + +### 海报墙没有显示图片 + +AB 默认使用 `mikanani.me` 的地址作为海报图片的源地址,如果没有显示图片说明你访问 AB 主页的主机网络环境不能访问这些图片。 + +## 3.0 是如何管理番剧的 + +升级到 3.0 之后 AB 可以在 WebUI 中一键管理番剧种子和下载规则。所以依赖的是种子的下载路径和规则名称。 +如果你手动在 QB 中更改了种子的下载路径,那么可能会碰到通知没有海报,删除种子不起作用等问题。 +请尽量在 AB 中操作管理番剧和种子。 + +## 下载以及关键词过滤 + +### 下载路径填写 + +**下载路径** 到底写什么? +- 这个参数只要和你 qBittorrent 中的参数保持一致即可。 + - Docker:比如 qB 中是 `/downloads` 那就写 `/downloads/Bangumi`,`Bangumi`可以任意更改。 + - Linux/macOS:如果是 `/home/usr/downloads` 或者 `/User/UserName/Downloads` 只要在最后再加一行 `Bangumi` 就行。 + - Windows:`D:\Media\`, 改为 `D:\Media\Bangumi` + +### 没有开始自动下载怎么办: + +- 检查 AutoBangumi 的日志,如果日志一切正常,说明是 qBittorrent 的设置问题,检查: + - 设置 >> RSS >> 启用 RSS Torrent 自动下载 + - Options >> RSS >> Enable auto downloading of RSS torrents + - 设置 >> RSS >> 启用获取 RSS 订阅 + - Options >> RSS >> Enable fetching RSS feeds + - 检查 qb 配置,看是否有权限新建文件夹 + +### 下载没有存储在正确的目录中 + +- 检查 [下载路径](###下载路径填写) 是否正确。 +- 检查 qBittorrent 的配置,PGID 与 PUID ,看是否有权限新建文件夹。可以尝试手动下载任意种子并且指定目录,如果出现错误或者未新建目录为文件夹权限问题。 +- 检查 qBittorrent 的默认配置,Saving Management 选项请选择手动保存,「保存管理 >> 默认种子管理模式 >> 手动」 + +### 下载很多没有订阅的番剧怎么办? + +- 检查一下蜜柑订阅是否订阅了一部番剧的全部字幕组。请一部番剧只订阅一个组,最好开启高级订阅。 + - 高级定于在 蜜柑计划 的用户设置中开启 +- 正则过滤不到位,请参考下一节拓展正则表达式。 +- 如果以上都没有出现,请带上 LOG 反馈至 [ISSUE][ISSUE]。 + +### 过滤关键词怎么写。 + +AB 中的过滤关键词是正则表达式,只会在建立规则的时候添加,后续如果要拓展规则,3.0 版本之后可以在 WebUI 中对每个番剧进行单独定义。 +- 过滤关键词是正则表达式,只需要把不需要的关键词用 `|` 间隔开即可。 +- 默认 `720|\d+-\d+` 这个规则会过滤掉所有合集和 720P 的番剧,如果要添加,请在部署 AB 之前添加完成,后续修改环境变量只会影响到新添加的规则。 +- 常用正则关键词(中间用 `|` )隔开: + - `720` 过滤 720、720P、720p 等等 + - `\d+-\d+` 过滤合集,比如 [1-12] + - `[Bb]aha` 过滤 Baha 的番剧 + - `[Bb]ilibili`、`[Bb]-Global` 过滤 Bilibili 的番剧 + - `繁`、`CHT` 过滤繁体字幕 +- 如果想要命中关键词,请在 QB 包含中用这种形式添加:`XXXXX+1080P\+` ,其中 `1080P\+` 表示命中 1080P+ 的番剧。 + +### 第一次部署出了问题下了很多不想下的番剧怎么办? + +1. 删除 QB 中多余的自动下载规则,和文件。 +2. 检查订阅,和过滤规则。 +3. 在浏览器中访问 resetRule API 地址 `http://localhost:7892/api/v1/resetRule` ,重置规则。 +4. 重启一下 AB 。 + +### AB 中识别的 RSS 条目比订阅的少 + +新版本中 AB 的过滤器也会默认过滤所有 RSS 条目,在设置的时候请不要一股脑全部加上过滤。如果想要细分下载,请在 WebUI 中对每个番剧进行单独配置。 + +### 过滤关键词不起作用 + +- 请检查是否正确设置了**全局过滤**参数。 +- 请在 QB 的 RSS 自动下载规则中检查,可以看右侧命中的 RSS,调整下载规则,点击 save 之后可以看到是哪个关键词出现错误。 + +## 🎬 番剧补全相关 + +### 番剧补全不起作用 + +- 请检查是否正确设置了 **番剧补全** 参数。 +- 旧版本的 AB 不支持修改参数临时启用补全,请清除数据并重新部署。 +- 2.5.15 版本之后的 AB 支持临时启用。 + +## 📁 重命名相关 + +### 解析错误 `NOT match with XXXXX` + +- AB 暂时不支持解析合集,合集请通过 API 添加。 +- 如果非合集,请在 issue 中反馈问题。 + +### `Rename failed` 或者重命名失败怎么办? + +- 检查文件路径,标准存储路径应为 `/title/Season/Episode.mp4` 如果不为标准格式路径会导致命名错误。发生这类错误请排查 qbittorrent 的配置。 +- 非上述问题,请到 issue 反馈。 + +### 没有自动重命名怎么办? + +- 请检查 QB 中种子分类是否在 `Bangumi` 类中。 +- AB 只会重命名已经下载的文件。 + +### 如何让 AB 重命名非 AB 添加的番剧 + +- 只需要把种子的类别更改为 `Bangumi` 即可。 +- 需要注意的是,需要种子存放在 `Title/Season X/` 文件夹下才能正常触发重命名。 + +### 如何重命名合集 + +1. 把合集的类别更改为 `Bangumi`。 +2. 把合集的存储路径更改为 `Title/Season X/`。 +3. 等待合集下载完成,重命名完成。 + +## 🌍 网络链接 + +### 无法连接到 qBittorrent + +- 检查 AB 中的 **下载器地址** 参数是否正确。 + - 如果你的 AB 和 QB 在同一个 Docker 网络中,可以尝试使用容器名称进行寻址,如:`http://qbittorrent:8080`。 + - 如果你的 AB 和 QB 在同一个 Docker 服务器中,可以尝试使用 Docker 网关地址进行访问,如:`http://172.17.0.1:8080`。 + - 如果 AB 网络模式不是 `host` 请不要使用 `127.0.0.1` 来访问 QB +- 在 Docker 中不同容器中无法互相访问,可以在 QB 的网络连接的链接中,设定链接 AB。 +- 如果 qBittorrent 使用 HTTPS 模式,请在 **下载器地址** 参数中添加 `https://` 前缀。 + +### `DNS/Connect ERROR` + +- 请检查网络连接,如果网络连接正常,请检查 DNS 解析。 +- 可以给 AB 添加一个 `dns=8.8.8.8`,如果是 HOST 模式可以忽略。 +- 如果 DNS 解析正常,添加代理。 +- 使用 TMDB 请添加代理。 + +### 如何给 Mikanani 添加代理 + +AB 现在提供三种代理模式 +1. HTTP 以及 Socks 代理 + + 老版本的 AB 就有这项功能,升级到 2.6 版本之后只需要在 WebUI 中检查代理配置即可正常访问蜜柑计划。 + + 不过这时候 qBittorrent 无法正常访问蜜柑计划的 RSS 和种子地址,因此需要在 qBittorrent 中添加代理。详情可以查看 #198 + +2. 自定义反向代理 URL + + 2.6 版本的 AB 在配置中增加了 `custom_url` 选项,可以自定义反向代理的 URL。 + 可以在配置中设置为自己正确设置的反代 URL。这样 AB 就会使用自定义的 URL 来访问蜜柑计划。并且 QB 也可以正常下载。 + +3. AB 作为反代中转 + + 在 AB 配置代理之后,AB 自身可以作为本地的反代中转。不过目前仅开放 RSS 相关功能的反代。 + 这时候只需要把 `custom_url` 设置为 `http://abhost:abport` 即可。 `abhost` 为 AB 的 IP 地址,`abport` 为 AB 的端口。 + 此时 AB 会把自身地址推送给 qBittorrent,qBittorrent 会使用 AB 的地址作为反代来访问蜜柑计划。 + + 请注意,此时如果你没有用 NGINX 等工具对 AB 进行反代,请填入 `http://` 来保证程序正常运行。 + 注意点2: 请不要在同时使用代理的情况下在 `custom_url` 中使用容器寻址,或者 Docker 的容器或者网关地址。转跳代理之后可能会无法访问 RSS。 + +## 🐬 Docker 相关 + +### 如何自动更新 + +可以通过在 Docker 中运行一个 `watchtower` 的守护进程,守护进程会自动更新你的容器。 + +[watchtower](https://containrrr.dev/watchtower) 官方文档 + +### 使用 Docker compose 更新 + +如果你的 AB 使用 Docker compose 部署,可以使用 `docker-compose pull` 命令更新。 +拉取完成容器之后可以使用 `docker-compose up -d` 重启容器。 + +### 如果升级出现了问题需要怎么做 + +由于每个人配置可能不尽相同,现在升级可能会出现程序无法运行的问题,此时删除掉所有以前的数据以及生成的配置文件后重启容器。 +然后在 WebUI 中重新配置一下即可。 +如果你是老版本升级,请先参考[升级指南](/changelog/2.6)。 + +如果有上述没有覆盖的问题,请到 [ISSUE](https://github.com/EstrellaXD/Auto_Bangumi/issues) 按照 bug 模板反馈。 diff --git a/docs/faq/排错流程.md b/docs/faq/排错流程.md new file mode 100644 index 00000000..f55af72f --- /dev/null +++ b/docs/faq/排错流程.md @@ -0,0 +1,46 @@ +--- +title: 排错流程 +--- + +## 💡 通用排错流程 +1. 如果 AB 无法正常启动,请检查启动命令是否正确, 当前版本正确的启动命令为 `/init`, 如果发现启动命令不正确且不会修改,请尝试重新部署 AB。 +2. 部署完 AB 之后请先查看 Log。如果运行如下说明 AB 运行正常,且与 QB 连接良好: + ``` + [2022-07-09 21:55:19,164] INFO: _ ____ _ + [2022-07-09 21:55:19,165] INFO: /\ | | | _ \ (_) + [2022-07-09 21:55:19,166] INFO: / \ _ _| |_ ___ | |_) | __ _ _ __ __ _ _ _ _ __ ___ _ + [2022-07-09 21:55:19,167] INFO: / /\ \| | | | __/ _ \| _ < / _` | '_ \ / _` | | | | '_ ` _ \| | + [2022-07-09 21:55:19,167] INFO: / ____ \ |_| | || (_) | |_) | (_| | | | | (_| | |_| | | | | | | | + [2022-07-09 21:55:19,168] INFO: /_/ \_\__,_|\__\___/|____/ \__,_|_| |_|\__, |\__,_|_| |_| |_|_| + [2022-07-09 21:55:19,169] INFO: __/ | + [2022-07-09 21:55:19,169] INFO: |___/ + [2022-07-09 21:55:19,170] INFO: Version 3.0.1 Author: EstrellaXD Twitter: https://twitter.com/Estrella_Pan + [2022-07-09 21:55:19,171] INFO: GitHub: https://github.com/EstrellaXD/Auto_Bangumi/ + [2022-07-09 21:55:19,172] INFO: Starting AutoBangumi... + [2022-07-09 21:55:20,717] INFO: Add RSS Feed successfully. + [2022-07-09 21:55:21,761] INFO: Start collecting RSS info. + [2022-07-09 21:55:23,431] INFO: Finished + [2022-07-09 21:55:23,432] INFO: Running.... + [2022-07-09 22:01:24,534] INFO: [NC-Raws] 继母的拖油瓶是我的前女友 - 01 (B-Global 1920x1080 HEVC AAC MKV) [0B604F3A].mkv >> 继母的拖油瓶是我的前女友 S01E01.mkv + ``` + 1. 如果出现如下 LOG,说明 AB 无法连接 qBittorrent,请检查 qBittorrent 是否正常运行,如果 qBittorrent 正常运行,转跳 [网络问题](/faq/常见问题#🌍-网络链接) 部分进行排查。 + ``` + [2022-07-09 22:01:24,534] WARNING: Cannot connect to qBittorrent, wait 5min and retry + ``` + 2. 如果出现如下 LOG,说明 AB 无法连接到 Mikan RSS,请转跳到 [网络问题](/faq/常见问题#🌍-网络链接) 部分进行排查。 + ``` + [2022-07-09 21:55:21,761] INFO: Start collecting RSS info. + [2022-07-09 22:01:24,534] WARNING: Connected Failed,please check DNS/Connection + ``` +3. 如果此时 QB 中没有下载任务,请转到 RSS 自动下载规则页面,检查 AB 建立的规则是否正确。 + 1. 查看 RSS 订阅,如果是正常的 RSS 图标,说明 RSS 订阅正常,如果是**问题图标**,说明 RSS 订阅有问题,请检查 qBittorrent 与 Mikan RSS 的连通性。 + 2. 如果没有任何下载规则,请检查 RSS 订阅是否是空白,`filter` 是否设置太多过滤值,转跳 [过滤问题](/faq/常见问题#下载以及关键词过滤) 。 + 3. 检查添加的规则是否是正确的,如果出现错误,请到 [issue](https://www.github.com/EstrellaXD/Auto_Bangumi/issues) 反馈。 + 4. 如果有下载规则没有下载,点击规则,并且检查右侧是否命中条目。如果没有命中条目,请删除一下过滤值。 + 5. 检查自动下载规则中「总是暂停」是否关闭 +4. 此时 QB 应该存在下载任务。 + 1. 如果下载任务出现路径问题,请检查 QB 设置中的「保存管理」中的「默认种子管理模式」是否为「手动」,若不是请调整为「手动」。 + 2. 如果下载全部为感叹号,或者下载路径中没有新建归类文件夹,请检查 QB 的权限。 +5. 如果上述排查均不能生效,请尝试重新部署一个新的 qBittorrent。 +6. 如果仍然无效,请带着 LOG 到 [issue](https://www.github.com/EstrellaXD/Auto_Bangumi/issues) 反馈。 + diff --git a/docs/home/index.md b/docs/home/index.md new file mode 100644 index 00000000..34550861 --- /dev/null +++ b/docs/home/index.md @@ -0,0 +1,99 @@ +--- +title: 项目说明 +--- + +

+ + + + + +

+ + +## 项目说明 + + +

+ AutoBangumi WebUI +

+ +**`AutoBangumi`** 是从 [Mikan Project](https://mikanani.me) 全自动追番整理下载工具。 +只需要在 [Mikan Project](https://mikanani.me) 上订阅番剧,就可以全自动追番、下载并整理文件, +整理后的番剧名称和目录可以直接被 [Plex]()、[Jellyfin]() 等媒体库软件识别,无需二次刮削。 + +## 功能说明 + +- 简易单次配置就能持续使用 +- 无需介入的 `RSS` 解析器,解析番组信息并且自动生成下载规则。 +- 番剧文件整理: + + ``` + Bangumi + ├── bangumi_A_title + │   ├── Season 1 + │   │   ├── A S01E01.mp4 + │   │   ├── A S01E02.mp4 + │   │   ├── A S01E03.mp4 + │   │   └── A S01E04.mp4 + │   └── Season 2 + │      ├── A S02E01.mp4 + │      ├── A S02E02.mp4 + │      ├── A S02E03.mp4 + │      └── A S02E04.mp4 + ├── bangumi_B_title + │   └─── Season 1 + ``` + +- 全自动重命名,重命名后 99% 以上的番剧可以直接被媒体库软件直接刮削 + + ``` + [Lilith-Raws] Kakkou no Iinazuke - 07 [Baha][WEB-DL][1080p][AVC AAC][CHT][MP4].mp4 + >> + Kakkou no Iinazuke S01E07.mp4 + ``` + +- 自定义重命名,可以根据上级文件夹对所有子文件重命名。 +- 季中追番可以补全当季遗漏的所有剧集 +- 高度可自定义的功能选项,可以针对不同媒体库软件微调 +- 无需维护完全无感使用 +- 内置 TDMB 解析器,可以直接生成完整的 TMDB 格式的文件以及番剧信息。 +- 对于 Mikan RSS 的反代支持。 + +## 相关群组 + +- 更新推送:[Telegram Channel](https://t.me/autobangumi_update) +- Bug 反馈群:[Telegram](https://t.me/+yNisOnDGaX5jMTM9) + +## 致谢 + +感谢 [Sean](https://github.com/findix) 提供的大量帮助 + +## 贡献 + +欢迎提供 ISSUE 或者 PR + + + + + +## 传播声明 + +由于 AutoBangumi 为非正规版权渠道获取番剧,因此: + +- **请勿**将 AutoBangumi 用于商业用途。 +- **请勿**将 AutoBangumi 制作为视频内容,于境内视频网站(版权利益方)传播。 +- **请勿**将 AutoBangumi 用于任何违反法律法规的行为。 + + +AutoBangumi 仅供学习交流使用。 + +## Licence + +[MIT licence](https://github.com/EstrellaXD/Auto_Bangumi/blob/main/LICENSE) diff --git a/docs/image/config/downloader.png b/docs/image/config/downloader.png new file mode 100644 index 00000000..6109b29c Binary files /dev/null and b/docs/image/config/downloader.png differ diff --git a/docs/image/config/manager.png b/docs/image/config/manager.png new file mode 100644 index 00000000..24e21f6b Binary files /dev/null and b/docs/image/config/manager.png differ diff --git a/docs/image/config/notifier.png b/docs/image/config/notifier.png new file mode 100644 index 00000000..88a86c6e Binary files /dev/null and b/docs/image/config/notifier.png differ diff --git a/docs/image/config/parser.png b/docs/image/config/parser.png new file mode 100644 index 00000000..262be48d Binary files /dev/null and b/docs/image/config/parser.png differ diff --git a/docs/image/config/program.png b/docs/image/config/program.png new file mode 100644 index 00000000..84733b8a Binary files /dev/null and b/docs/image/config/program.png differ diff --git a/docs/image/config/proxy.png b/docs/image/config/proxy.png new file mode 100644 index 00000000..385819e5 Binary files /dev/null and b/docs/image/config/proxy.png differ diff --git a/docs/image/dark-icon.png b/docs/image/dark-icon.png deleted file mode 100644 index 6186ffd0..00000000 Binary files a/docs/image/dark-icon.png and /dev/null differ diff --git a/docs/image/dev/branch.png b/docs/image/dev/branch.png new file mode 100644 index 00000000..b45bd46f Binary files /dev/null and b/docs/image/dev/branch.png differ diff --git a/docs/image/dsm/create.png b/docs/image/dsm/create.png new file mode 100644 index 00000000..0aa57b94 Binary files /dev/null and b/docs/image/dsm/create.png differ diff --git a/docs/image/dsm/install-docker.png b/docs/image/dsm/install-docker.png new file mode 100644 index 00000000..b78d0fe4 Binary files /dev/null and b/docs/image/dsm/install-docker.png differ diff --git a/docs/image/dsm/new-compose.png b/docs/image/dsm/new-compose.png new file mode 100644 index 00000000..9012aac1 Binary files /dev/null and b/docs/image/dsm/new-compose.png differ diff --git a/docs/image/icons/dark-icon.svg b/docs/image/icons/dark-icon.svg new file mode 100644 index 00000000..f42427b9 --- /dev/null +++ b/docs/image/icons/dark-icon.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/image/icons/light-icon.svg b/docs/image/icons/light-icon.svg new file mode 100644 index 00000000..dc0c2102 --- /dev/null +++ b/docs/image/icons/light-icon.svg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/image/icons/mikan-icon.ico b/docs/image/icons/mikan-icon.ico new file mode 100644 index 00000000..8077da2f Binary files /dev/null and b/docs/image/icons/mikan-icon.ico differ diff --git a/docs/image/icons/mikan-pic.png b/docs/image/icons/mikan-pic.png new file mode 100644 index 00000000..823dfafd Binary files /dev/null and b/docs/image/icons/mikan-pic.png differ diff --git a/docs/image/icons/plex-icon.png b/docs/image/icons/plex-icon.png new file mode 100644 index 00000000..7d73b91c Binary files /dev/null and b/docs/image/icons/plex-icon.png differ diff --git a/docs/image/icons/qbittorrent-logo.svg b/docs/image/icons/qbittorrent-logo.svg new file mode 100644 index 00000000..59a79b0e --- /dev/null +++ b/docs/image/icons/qbittorrent-logo.svg @@ -0,0 +1,16 @@ + + + qbittorrent-new-light + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/image/icons/tmdb-icon.png b/docs/image/icons/tmdb-icon.png new file mode 100644 index 00000000..583d3d2b Binary files /dev/null and b/docs/image/icons/tmdb-icon.png differ diff --git a/docs/image/light-icon.png b/docs/image/light-icon.png deleted file mode 100644 index a264ebf2..00000000 Binary files a/docs/image/light-icon.png and /dev/null differ diff --git a/docs/image/preview/webui-home.png b/docs/image/preview/webui-home.png new file mode 100644 index 00000000..1f3ac87a Binary files /dev/null and b/docs/image/preview/webui-home.png differ diff --git a/docs/image/preview/window.png b/docs/image/preview/window.png new file mode 100644 index 00000000..1dbd6263 Binary files /dev/null and b/docs/image/preview/window.png differ diff --git a/docs/image/rss/advanced-subscription.png b/docs/image/rss/advanced-subscription.png new file mode 100644 index 00000000..61713979 Binary files /dev/null and b/docs/image/rss/advanced-subscription.png differ diff --git a/docs/image/rss/rss-token.png b/docs/image/rss/rss-token.png new file mode 100644 index 00000000..31ade6c9 Binary files /dev/null and b/docs/image/rss/rss-token.png differ diff --git a/docs/image/window.png b/docs/image/window.png deleted file mode 100644 index f2b61272..00000000 Binary files a/docs/image/window.png and /dev/null differ diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..cd6699a1 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,111 @@ +--- +# https://vitepress.dev/reference/default-theme-home-page +layout: home + +title: AutoBangumi +titleTemplate: 自动追番,解放双手! + +hero: + name: AutoBangumi + text: 自动追番,解放双手! + tagline: 从 Mikan Project 全自动 订阅解析、下载管理、重命名整理 +# image: +# dark: /image/icons/dark-logo.svg +# light: /image/icons/light-logo.svg +# alt: AutoBangumi WebUI + actions: + - theme: brand + text: 快速开始 + link: /deploy/quick-start + - theme: alt + text: 项目说明 + link: /home/ + - theme: alt + text: 更新日志 + link: /changelog/3.0 + +features: + - icon: + src: /image/icons/mikan-pic.png + title: Mikan Project 订阅源 + details: 自动识别蜜柑计划 RSS 订阅格式,无需手动输入番剧,仅需订阅即可自动解析、下载、整理。 + - icon: + src: /image/icons/qbittorrent-logo.svg + title: qBitTorrent 下载器 + details: 使用 qBitTorrent 共享下载番剧资源,在 AutoBangumi 中可管理已有番剧、下载旧番、删除番剧。 + - icon: + src: /image/icons/tmdb-icon.png + title: The Movie DB 解析匹配 + details: 可根据 TMDB 最大程度匹配对应番剧信息,保证对多个字幕组的资源也能正确匹配与解析。 + - icon: + src: /image/icons/plex-icon.png + title: Plex / Jellyfin / Infuse ... + details: 根据番剧匹配结果自动整理资源文件名,统一目录结构,保证各类媒体库元信息刮削成功率。 +--- + + +
+
+ +## 致谢声明 + +### Credits +Thanks to +- [Mikan Project](https://mikanani.me) for providing the so great anime resource. +- [VitePress](https://vitepress.dev) for providing a great documentation framework. +- [qBitTorrent](https://www.qbittorrent.org) for providing a great downloader. +- [Plex](https://www.plex.tv) / [Jellyfin](https://jellyfin.org) for providing some great self-host media libraries. +- [Infuse](https://firecore.com/infuse) for providing an elegant video player. +- [DanDan Play](https://www.dandanplay.com) for providing a great danmaku player. +- Every bangumi production team / translator team / fans. + +### Contributors + +[ + ![](https://contrib.rocks/image?repo=EstrellaXD/Auto_Bangumi){class=contributors-avatar} +](https://github.com/EstrellaXD/Auto_Bangumi/graphs/contributors) + +## 传播声明 + +由于 AutoBangumi 为非正规版权渠道获取番剧,因此: + +- **请勿**将 AutoBangumi 用于商业用途。 +- **请勿**将 AutoBangumi 制作为视频内容,于境内视频网站(版权利益方)传播。 +- **请勿**将 AutoBangumi 用于任何违反法律法规的行为。 + +
+
+ + + + + diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 00000000..d3332110 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,20 @@ +{ + "private": true, + "scripts": { + "docs:dev": "vitepress dev", + "docs:build": "vitepress build && mkdir -p .vitepress/dist/image && cp -rf image/icons .vitepress/dist/image/", + "docs:preview": "vitepress preview", + "deploy:preview": "vercel --cwd .vitepress/dist" + }, + "devDependencies": { + "@vue/tsconfig": "^0.4.0", + "medium-zoom": "^1.0.8", + "typescript": "4.9.5", + "vercel": "31.0.1", + "vitepress": "1.0.0-beta.3", + "vue": "3.3.4" + }, + "dependencies": { + "@vercel/analytics": "^1.0.1" + } +} diff --git a/docs/pnpm-lock.yaml b/docs/pnpm-lock.yaml new file mode 100644 index 00000000..28ebe1d8 --- /dev/null +++ b/docs/pnpm-lock.yaml @@ -0,0 +1,7114 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@vercel/analytics': + specifier: ^1.0.1 + version: 1.0.1 + +devDependencies: + '@vue/tsconfig': + specifier: ^0.4.0 + version: 0.4.0 + medium-zoom: + specifier: ^1.0.8 + version: 1.0.8 + typescript: + specifier: 4.9.5 + version: 4.9.5 + vercel: + specifier: 31.0.1 + version: 31.0.1(@types/node@14.18.33) + vitepress: + specifier: 1.0.0-beta.3 + version: 1.0.0-beta.3(@algolia/client-search@4.18.0)(@types/node@14.18.33)(search-insights@2.6.0) + vue: + specifier: 3.3.4 + version: 3.3.4 + +packages: + + /@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0): + resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==} + dependencies: + '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0) + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + - search-insights + dev: true + + /@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0): + resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==} + peerDependencies: + search-insights: '>= 1 < 3' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) + search-insights: 2.6.0 + transitivePeerDependencies: + - '@algolia/client-search' + - algoliasearch + dev: true + + /@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0): + resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) + '@algolia/client-search': 4.18.0 + algoliasearch: 4.18.0 + dev: true + + /@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0): + resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==} + peerDependencies: + '@algolia/client-search': '>= 4.9.1 < 6' + algoliasearch: '>= 4.9.1 < 6' + dependencies: + '@algolia/client-search': 4.18.0 + algoliasearch: 4.18.0 + dev: true + + /@algolia/cache-browser-local-storage@4.18.0: + resolution: {integrity: sha512-rUAs49NLlO8LVLgGzM4cLkw8NJLKguQLgvFmBEe3DyzlinoqxzQMHfKZs6TSq4LZfw/z8qHvRo8NcTAAUJQLcw==} + dependencies: + '@algolia/cache-common': 4.18.0 + dev: true + + /@algolia/cache-common@4.18.0: + resolution: {integrity: sha512-BmxsicMR4doGbeEXQu8yqiGmiyvpNvejYJtQ7rvzttEAMxOPoWEHrWyzBQw4x7LrBY9pMrgv4ZlUaF8PGzewHg==} + dev: true + + /@algolia/cache-in-memory@4.18.0: + resolution: {integrity: sha512-evD4dA1nd5HbFdufBxLqlJoob7E2ozlqJZuV3YlirNx5Na4q1LckIuzjNYZs2ddLzuTc/Xd5O3Ibf7OwPskHxw==} + dependencies: + '@algolia/cache-common': 4.18.0 + dev: true + + /@algolia/client-account@4.18.0: + resolution: {integrity: sha512-XsDnlROr3+Z1yjxBJjUMfMazi1V155kVdte6496atvBgOEtwCzTs3A+qdhfsAnGUvaYfBrBkL0ThnhMIBCGcew==} + dependencies: + '@algolia/client-common': 4.18.0 + '@algolia/client-search': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /@algolia/client-analytics@4.18.0: + resolution: {integrity: sha512-chEUSN4ReqU7uRQ1C8kDm0EiPE+eJeAXiWcBwLhEynfNuTfawN9P93rSZktj7gmExz0C8XmkbBU19IQ05wCNrQ==} + dependencies: + '@algolia/client-common': 4.18.0 + '@algolia/client-search': 4.18.0 + '@algolia/requester-common': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /@algolia/client-common@4.18.0: + resolution: {integrity: sha512-7N+soJFP4wn8tjTr3MSUT/U+4xVXbz4jmeRfWfVAzdAbxLAQbHa0o/POSdTvQ8/02DjCLelloZ1bb4ZFVKg7Wg==} + dependencies: + '@algolia/requester-common': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /@algolia/client-personalization@4.18.0: + resolution: {integrity: sha512-+PeCjODbxtamHcPl+couXMeHEefpUpr7IHftj4Y4Nia1hj8gGq4VlIcqhToAw8YjLeCTfOR7r7xtj3pJcYdP8A==} + dependencies: + '@algolia/client-common': 4.18.0 + '@algolia/requester-common': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /@algolia/client-search@4.18.0: + resolution: {integrity: sha512-F9xzQXTjm6UuZtnsLIew6KSraXQ0AzS/Ee+OD+mQbtcA/K1sg89tqb8TkwjtiYZ0oij13u3EapB3gPZwm+1Y6g==} + dependencies: + '@algolia/client-common': 4.18.0 + '@algolia/requester-common': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /@algolia/logger-common@4.18.0: + resolution: {integrity: sha512-46etYgSlkoKepkMSyaoriSn2JDgcrpc/nkOgou/lm0y17GuMl9oYZxwKKTSviLKI5Irk9nSKGwnBTQYwXOYdRg==} + dev: true + + /@algolia/logger-console@4.18.0: + resolution: {integrity: sha512-3P3VUYMl9CyJbi/UU1uUNlf6Z8N2ltW3Oqhq/nR7vH0CjWv32YROq3iGWGxB2xt3aXobdUPXs6P0tHSKRmNA6g==} + dependencies: + '@algolia/logger-common': 4.18.0 + dev: true + + /@algolia/requester-browser-xhr@4.18.0: + resolution: {integrity: sha512-/AcWHOBub2U4TE/bPi4Gz1XfuLK6/7dj4HJG+Z2SfQoS1RjNLshZclU3OoKIkFp8D2NC7+BNsPvr9cPLyW8nyQ==} + dependencies: + '@algolia/requester-common': 4.18.0 + dev: true + + /@algolia/requester-common@4.18.0: + resolution: {integrity: sha512-xlT8R1qYNRBCi1IYLsx7uhftzdfsLPDGudeQs+xvYB4sQ3ya7+ppolB/8m/a4F2gCkEO6oxpp5AGemM7kD27jA==} + dev: true + + /@algolia/requester-node-http@4.18.0: + resolution: {integrity: sha512-TGfwj9aeTVgOUhn5XrqBhwUhUUDnGIKlI0kCBMdR58XfXcfdwomka+CPIgThRbfYw04oQr31A6/95ZH2QVJ9UQ==} + dependencies: + '@algolia/requester-common': 4.18.0 + dev: true + + /@algolia/transporter@4.18.0: + resolution: {integrity: sha512-xbw3YRUGtXQNG1geYFEDDuFLZt4Z8YNKbamHPkzr3rWc6qp4/BqEeXcI2u/P/oMq2yxtXgMxrCxOPA8lyIe5jw==} + dependencies: + '@algolia/cache-common': 4.18.0 + '@algolia/logger-common': 4.18.0 + '@algolia/requester-common': 4.18.0 + dev: true + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@babel/code-frame@7.22.5: + resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.22.5 + dev: true + + /@babel/compat-data@7.22.5: + resolution: {integrity: sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.22.5: + resolution: {integrity: sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-module-transforms': 7.22.5 + '@babel/helpers': 7.22.5 + '@babel/parser': 7.22.5 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.22.5: + resolution: {integrity: sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.22.5: + resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.22.5: + resolution: {integrity: sha512-m1EP3lVOPptR+2DwD125gziZNcmoNSHGmJROKoy87loWUQyJaVXDgpmruWqDARZSmtYQ+Dl25okU8+qhVzuykw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-compilation-targets@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.22.5 + '@babel/core': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + browserslist: 4.21.9 + lru-cache: 5.1.1 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + regexpu-core: 5.3.2 + semver: 6.3.0 + dev: true + + /@babel/helper-define-polyfill-provider@0.4.0(@babel/core@7.22.5): + resolution: {integrity: sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.2 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.22.5: + resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.22.5: + resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-hoist-variables@7.22.5: + resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-member-expression-to-functions@7.22.5: + resolution: {integrity: sha512-aBiH1NKMG0H2cGZqspNvsaBe6wNGjbJjuLy29aU+eDZjSbbN53BaxlpB02xm9v34pLTZ1nIQPFYn2qMZoa5BQQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-module-imports@7.22.5: + resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-module-transforms@7.22.5: + resolution: {integrity: sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression@7.22.5: + resolution: {integrity: sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-plugin-utils@7.22.5: + resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-wrap-function': 7.22.5 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers@7.22.5: + resolution: {integrity: sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-member-expression-to-functions': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access@7.22.5: + resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.22.5: + resolution: {integrity: sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-split-export-declaration@7.22.5: + resolution: {integrity: sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/helper-string-parser@7.22.5: + resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-identifier@7.22.5: + resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-validator-option@7.22.5: + resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.22.5: + resolution: {integrity: sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.22.5 + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers@7.22.5: + resolution: {integrity: sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.5 + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.22.5: + resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.22.5: + resolution: {integrity: sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.22.5 + dev: true + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-NP1M5Rf+u2Gw9qfSO4ihjcTGW5zXTi36ITLd4/EoAcEhIZ0yjMqmftDNl3QC19CX7olhrjpyU454g/2W7X0jvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-31Bb65aZaUwqCbWMnZPduIZxCBngHFlzyN6Dq6KAJjtx+lx6ohKHubc61OomYi7XwVD4Ol0XCVz4h+pYFR048g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-transform-optional-chaining': 7.22.5(@babel/core@7.22.5) + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.5): + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + dev: true + + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.5): + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.5): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.5): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.5): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-assertions@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-attributes@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.5): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.5): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.5): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.5): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.5): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.5): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.22.5): + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-arrow-functions@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-async-generator-functions@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-async-to-generator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-module-imports': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.22.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-block-scoping@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-EcACl1i5fSQ6bt+YGuU/XGCeZKStLmyVGytWkpyhCLeQVA0eu6Wtiw92V+I1T/hnezUv7j74dA/Ro69gWcU+hg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-class-properties@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-class-static-block@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-SPToJ5eYZLxlnp1UzdARpOGeC2GbHvr9d/UV0EukuVx8atktg194oe+C5BqQ8jRTkgLRVOPYeXRSBg1IlMoVRA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-classes@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-optimise-call-expression': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.22.5 + dev: true + + /@babel/plugin-transform-destructuring@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-GfqcFuGW8vnEqTUBM7UtPd5A4q797LTvvwKxXTgRsFjoqaJiEg9deBG6kWeQYkVEL569NpnmpC0Pkr/8BLKGnQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dotall-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-dynamic-import@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-0MC3ppTB1AMxd8fXjSrbPa7LT9hrImt+/fcj+Pg5YMD7UQyWp/02+JWpdnCymmsXwIx5Z+sYn1bwCn4ZJNvhqQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-export-namespace-from@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-X4hhm7FRnPgd4nDA4b/5V280xCx6oL7Oob5+9qVS5C13Zq4bh1qq7LU0GgRU6b5dBWBvhGaXYVB4AcN6+ol6vg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-for-of@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-3kxQjX1dU9uudwSshyLeEipvrLjBCVthCgeTp6CzE/9JYrlAIaeekVxRpCWsDDfYTfRZRoCeZatCQvwo+wvK8A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-function-name@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-function-name': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-json-strings@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-DuCRB7fu8MyTLbEQd1ew3R85nx/88yMoqo2uPSjevMj3yoN7CDM8jkgrY0wmVxfJZyJ/B9fE1iq7EQppWQmR5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-literals@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-logical-assignment-operators@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-MQQOUW1KL8X0cDWfbwYP+TbVbZm16QmQXJQ+vndPtH/BoO0lOKpVoEDMI7+PskYxH+IiE0tS8xZye0qr1lGzSA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-member-expression-literals@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-modules-amd@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-R+PTfLTcYEmb1+kK7FNkhQ1gP4KgjpSO6HfH9+f8/yfp2Nt3ggBjiVpRwmwTlfqZLafYKJACy36yDXlEmI9HjQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-module-transforms': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-B4pzOXj+ONRmuaQTg05b3y/4DuFz3WcCNAXPLb2Q0GT0TrGKGxNKV4jwsXts+StaM0LQczZbOpj8o1DLPDJIiA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-module-transforms': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-emtEpoaTMsOs6Tzz+nbmcePl6AKVtS1yC4YNAeMun9U8YCsgadPNxnOPQ8GhHFB2qdx+LZu9LgoC0Lthuu05DQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-module-transforms': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-new-target@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-nullish-coalescing-operator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-6CF8g6z1dNYZ/VXok5uYkkBBICHZPiGEl7oDnAx2Mt1hlHVHOSIKWJaXHjQJA5VB43KZnXZDIexMchY4y2PGdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-numeric-separator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-NbslED1/6M+sXiwwtcAB/nieypGw02Ejf4KtDeMkCEpP6gWFMX1wI9WKYua+4oBneCCEmulOkRpwywypVZzs/g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-object-rest-spread@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-Kk3lyDmEslH9DnvCDA1s1kkd3YWQITiBOHngOtDL9Pt6BZjzqb6hiOlb8VfjiiQJ2unmegBqZu0rx5RxJb5vmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.5 + '@babel/core': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-object-super@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-replace-supers': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-optional-catch-binding@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-pH8orJahy+hzZje5b8e2QIlBWQvGpelS76C63Z+jhZKsmzfNaPQ+LaW6dcJ9bxTpo1mtXbgHwy765Ro3jftmUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-optional-chaining@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) + dev: true + + /@babel/plugin-transform-parameters@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-AVkFUBurORBREOmHRKo06FjHYgjrabpdqRSwq6+C7R5iTCZOsM4QbcB27St0a4U6fffyAOqh3s/qEfybAhfivg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-private-methods@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-private-property-in-object@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-/9xnaTTJcVoBtSSmrVyhtSvO3kbqS2ODoh2juEU72c3aYonNF0OMGiaz2gjukyKM2wBBYJP38S4JiE0Wfb5VMQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-property-literals@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-regenerator@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-rR7KePOE7gfEtNTh9Qw+iO3Q/e4DEsoQ+hdvM6QUDH7JRJ5qxq5AA52ZzBWbI5i9lfNuvySgOGP8ZN7LAmaiPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-spread@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.22.5 + dev: true + + /@babel/plugin-transform-sticky-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-template-literals@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-typescript@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-unicode-escapes@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-biEmVg1IYB/raUO5wT1tgfacCef15Fbzhkx493D3urBI++6hpJ+RFG4SrWMn0NEZLfvilqKf3QDrRVZHo08FYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-property-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/plugin-transform-unicode-sets-regex@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-create-regexp-features-plugin': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + dev: true + + /@babel/preset-env@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.5 + '@babel/core': 7.22.5 + '@babel/helper-compilation-targets': 7.22.5(@babel/core@7.22.5) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.22.5) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.5) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.5) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-import-assertions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-import-attributes': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.5) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.5) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.5) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.22.5) + '@babel/plugin-transform-arrow-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-async-generator-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-async-to-generator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-block-scoped-functions': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-block-scoping': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-class-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-class-static-block': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-classes': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-computed-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-destructuring': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-duplicate-keys': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-dynamic-import': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-exponentiation-operator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-export-namespace-from': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-for-of': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-function-name': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-json-strings': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-logical-assignment-operators': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-member-expression-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-amd': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-systemjs': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-umd': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-named-capturing-groups-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-new-target': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-nullish-coalescing-operator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-numeric-separator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-object-rest-spread': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-object-super': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-optional-catch-binding': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-optional-chaining': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-parameters': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-private-methods': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-private-property-in-object': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-property-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-regenerator': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-reserved-words': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-shorthand-properties': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-spread': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-sticky-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-template-literals': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-typeof-symbol': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-escapes': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-property-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-regex': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-unicode-sets-regex': 7.22.5(@babel/core@7.22.5) + '@babel/preset-modules': 0.1.5(@babel/core@7.22.5) + '@babel/types': 7.22.5 + babel-plugin-polyfill-corejs2: 0.4.3(@babel/core@7.22.5) + babel-plugin-polyfill-corejs3: 0.8.1(@babel/core@7.22.5) + babel-plugin-polyfill-regenerator: 0.5.0(@babel/core@7.22.5) + core-js-compat: 3.31.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-modules@0.1.5(@babel/core@7.22.5): + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.5) + '@babel/plugin-transform-dotall-regex': 7.22.5(@babel/core@7.22.5) + '@babel/types': 7.22.5 + esutils: 2.0.3 + dev: true + + /@babel/preset-typescript@7.22.5(@babel/core@7.22.5): + resolution: {integrity: sha512-YbPaal9LxztSGhmndR46FmAbkJ/1fAsw293tSU+I5E5h+cnJ3d4GTwyUgGYmOXJYdGA+uNePle4qbaRzj2NISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.22.5 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-modules-commonjs': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-transform-typescript': 7.22.5(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.12.1: + resolution: {integrity: sha512-J5AIf3vPj3UwXaAzb5j1xM4WAQDX3EMgemF8rjCP3SoW09LfRKAXQKt6CoVYl230P6iWdRcBbnLDDdnqWxZSCA==} + dependencies: + regenerator-runtime: 0.13.11 + dev: true + + /@babel/runtime@7.22.5: + resolution: {integrity: sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + dev: true + + /@babel/template@7.22.5: + resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.5 + '@babel/parser': 7.22.5 + '@babel/types': 7.22.5 + dev: true + + /@babel/traverse@7.22.5: + resolution: {integrity: sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.22.5 + '@babel/generator': 7.22.5 + '@babel/helper-environment-visitor': 7.22.5 + '@babel/helper-function-name': 7.22.5 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.5 + '@babel/parser': 7.22.5 + '@babel/types': 7.22.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.22.5: + resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.22.5 + '@babel/helper-validator-identifier': 7.22.5 + to-fast-properties: 2.0.0 + dev: true + + /@cspotcode/source-map-support@0.8.1: + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + dev: true + + /@docsearch/css@3.5.1: + resolution: {integrity: sha512-2Pu9HDg/uP/IT10rbQ+4OrTQuxIWdKVUEdcw9/w7kZJv9NeHS6skJx1xuRiFyoGKwAzcHXnLp7csE99sj+O1YA==} + dev: true + + /@docsearch/js@3.5.1(@algolia/client-search@4.18.0)(search-insights@2.6.0): + resolution: {integrity: sha512-EXi8de5njxgP6TV3N9ytnGRLG9zmBNTEZjR4VzwPcpPLbZxxTLG2gaFyJyKiFVQxHW/DPlMrDJA3qoRRGEkgZw==} + dependencies: + '@docsearch/react': 3.5.1(@algolia/client-search@4.18.0)(search-insights@2.6.0) + preact: 10.15.1 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/react' + - react + - react-dom + - search-insights + dev: true + + /@docsearch/react@3.5.1(@algolia/client-search@4.18.0)(search-insights@2.6.0): + resolution: {integrity: sha512-t5mEODdLzZq4PTFAm/dvqcvZFdPDMdfPE5rJS5SC8OUq9mPzxEy6b+9THIqNM9P0ocCb4UC5jqBrxKclnuIbzQ==} + peerDependencies: + '@types/react': '>= 16.8.0 < 19.0.0' + react: '>= 16.8.0 < 19.0.0' + react-dom: '>= 16.8.0 < 19.0.0' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + react-dom: + optional: true + dependencies: + '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0)(search-insights@2.6.0) + '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.18.0)(algoliasearch@4.18.0) + '@docsearch/css': 3.5.1 + algoliasearch: 4.18.0 + transitivePeerDependencies: + - '@algolia/client-search' + - search-insights + dev: true + + /@edge-runtime/format@2.1.0: + resolution: {integrity: sha512-gc2qbYEIIJRczBApBPznVI1c5vZgzrZQOsFZnAxxFiYah9qldHiu1YEitzSvXI8X8ZgvAguuIiyIbpWz17nlXA==} + engines: {node: '>=14'} + dev: true + + /@edge-runtime/node-utils@2.0.3: + resolution: {integrity: sha512-JUSbi5xu/A8+D2t9B9wfirCI1J8n8q0660FfmqZgA+n3RqxD3y7SnamL1sKRE5/AbHsKs9zcqCbK2YDklbc9Bg==} + engines: {node: '>=14'} + dev: true + + /@edge-runtime/primitives@2.1.2: + resolution: {integrity: sha512-SR04SMDybALlhIYIi0hiuEUwIl0b7Sn+RKwQkX6hydg4+AKMzBNDFhj2nqHDD1+xkHArV9EhmJIb6iGjShwSzg==} + engines: {node: '>=14'} + dev: true + + /@edge-runtime/primitives@3.0.1: + resolution: {integrity: sha512-l5NNDcPkKW4N6qRmB8zzpCF6uRW1S808V/zm72z7b/aWwZUYbmEPPkzyhGAW0aQxLU1pGdZ8u2gNjamdaU6RXw==} + engines: {node: '>=14'} + dev: true + + /@edge-runtime/primitives@3.0.3: + resolution: {integrity: sha512-YnfMWMRQABAH8IsnFMJWMW+SyB4ZeYBPnR7V0aqdnew7Pq60cbH5DyFjS/FhiLwvHQk9wBREmXD7PP0HooEQ1A==} + engines: {node: '>=14'} + dev: true + + /@edge-runtime/vm@3.0.1: + resolution: {integrity: sha512-69twXLIcqVx0iNlc1vFqnXgka2CZi2c/QBAmMzXBk0M6mPG+ICCBh2dd+cv1K+HW2pfLuSW+EskkFXWGeCf1Vw==} + engines: {node: '>=14'} + dependencies: + '@edge-runtime/primitives': 3.0.1 + dev: true + + /@edge-runtime/vm@3.0.3: + resolution: {integrity: sha512-SPfI1JeIRNs/4EEE2Oc0X6gG3RqjD1TnKu2lwmwFXq0435xgZGKhc3UiKkYAdoMn2dNFD73nlabMKHBRoMRpxg==} + engines: {node: '>=14'} + dependencies: + '@edge-runtime/primitives': 3.0.3 + dev: true + + /@emotion/hash@0.9.1: + resolution: {integrity: sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==} + dev: true + + /@esbuild/android-arm64@0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.17.6: + resolution: {integrity: sha512-YnYSCceN/dUzUr5kdtUzB+wZprCafuD89Hs0Aqv9QSdwhYQybhXTaSTcrl6X/aWThn1a/j0eEpUBGOE7269REg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.6: + resolution: {integrity: sha512-bSC9YVUjADDy1gae8RrioINU6e1lCkg3VGVwm0QQ2E1CWcC4gnMce9+B6RpxuSsrsXsk1yojn7sp1fnG8erE2g==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.6: + resolution: {integrity: sha512-MVcYcgSO7pfu/x34uX9u2QIZHmXAB7dEiLQC5bBl5Ryqtpj9lT2sg3gNDEsrPEmimSJW2FXIaxqSQ501YLDsZQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.6: + resolution: {integrity: sha512-bsDRvlbKMQMt6Wl08nHtFz++yoZHsyTOxnjfB2Q95gato+Yi4WnRl13oC2/PJJA9yLCoRv9gqT/EYX0/zDsyMA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.6: + resolution: {integrity: sha512-xh2A5oPrYRfMFz74QXIQTQo8uA+hYzGWJFoeTE8EvoZGHb+idyV4ATaukaUvnnxJiauhs/fPx3vYhU4wiGfosg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.6: + resolution: {integrity: sha512-EnUwjRc1inT4ccZh4pB3v1cIhohE2S4YXlt1OvI7sw/+pD+dIE4smwekZlEPIwY6PhU6oDWwITrQQm5S2/iZgg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.6: + resolution: {integrity: sha512-Uh3HLWGzH6FwpviUcLMKPCbZUAFzv67Wj5MTwK6jn89b576SR2IbEp+tqUHTr8DIl0iDmBAf51MVaP7pw6PY5Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.6: + resolution: {integrity: sha512-bUR58IFOMJX523aDVozswnlp5yry7+0cRLCXDsxnUeQYJik1DukMY+apBsLOZJblpH+K7ox7YrKrHmJoWqVR9w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.6: + resolution: {integrity: sha512-7YdGiurNt7lqO0Bf/U9/arrPWPqdPqcV6JCZda4LZgEn+PTQ5SMEI4MGR52Bfn3+d6bNEGcWFzlIxiQdS48YUw==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.6: + resolution: {integrity: sha512-ujp8uoQCM9FRcbDfkqECoARsLnLfCUhKARTP56TFPog8ie9JG83D5GVKjQ6yVrEVdMie1djH86fm98eY3quQkQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.6: + resolution: {integrity: sha512-y2NX1+X/Nt+izj9bLoiaYB9YXT/LoaQFYvCkVD77G/4F+/yuVXYCWz4SE9yr5CBMbOxOfBcy/xFL4LlOeNlzYQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.6: + resolution: {integrity: sha512-09AXKB1HDOzXD+j3FdXCiL/MWmZP0Ex9eR8DLMBVcHorrWJxWmY8Nms2Nm41iRM64WVx7bA/JVHMv081iP2kUA==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.6: + resolution: {integrity: sha512-AmLhMzkM8JuqTIOhxnX4ubh0XWJIznEynRnZAVdA2mMKE6FAfwT2TWKTwdqMG+qEaeyDPtfNoZRpJbD4ZBv0Tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.6: + resolution: {integrity: sha512-Y4Ri62PfavhLQhFbqucysHOmRamlTVK10zPWlqjNbj2XMea+BOs4w6ASKwQwAiqf9ZqcY9Ab7NOU4wIgpxwoSQ==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.6: + resolution: {integrity: sha512-SPUiz4fDbnNEm3JSdUW8pBJ/vkop3M1YwZAVwvdwlFLoJwKEZ9L98l3tzeyMzq27CyepDQ3Qgoba44StgbiN5Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.6: + resolution: {integrity: sha512-a3yHLmOodHrzuNgdpB7peFGPx1iJ2x6m+uDvhP2CKdr2CwOaqEFMeSqYAHU7hG+RjCq8r2NFujcd/YsEsFgTGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.6: + resolution: {integrity: sha512-EanJqcU/4uZIBreTrnbnre2DXgXSa+Gjap7ifRfllpmyAU7YMvaXmljdArptTHmjrkkKm9BK6GH5D5Yo+p6y5A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.6: + resolution: {integrity: sha512-xaxeSunhQRsTNGFanoOkkLtnmMn5QbA0qBhNet/XLVsc+OVkpIWPHcr3zTW2gxVU5YOHFbIHR9ODuaUdNza2Vw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.6: + resolution: {integrity: sha512-gnMnMPg5pfMkZvhHee21KbKdc6W3GR8/JuE0Da1kjwpK6oiFU3nqfHuVPgUX2rsOx9N2SadSQTIYV1CIjYG+xw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.6: + resolution: {integrity: sha512-G95n7vP1UnGJPsVdKXllAJPtqjMvFYbN20e8RK8LVLhlTiSOH1sd7+Gt7rm70xiG+I5tM58nYgwWrLs6I1jHqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.6: + resolution: {integrity: sha512-96yEFzLhq5bv9jJo5JhTs1gI+1cKQ83cUpyxHuGqXVwQtY5Eq54ZEsKs8veKtiKwlrNimtckHEkj4mRh4pPjsg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.6: + resolution: {integrity: sha512-n6d8MOyUrNp6G4VSpRcgjs5xj4A91svJSaiwLIDWVWEsZtpN5FA9NlBbZHDmAJc2e8e6SF4tkBD3HAvPF+7igA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@gar/promisify@1.1.3: + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/resolve-uri@3.1.1: + resolution: {integrity: sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/sourcemap-codec@1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping@0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@jridgewell/trace-mapping@0.3.9: + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + dependencies: + '@jridgewell/resolve-uri': 3.1.1 + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /@jspm/core@2.0.1: + resolution: {integrity: sha512-Lg3PnLp0QXpxwLIAuuJboLeRaIhrgJjeuh797QADg3xz8wGLugQOS5DpsE8A6i6Adgzf+bacllkKZG3J0tGfDw==} + dev: true + + /@mapbox/node-pre-gyp@1.0.10: + resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==} + hasBin: true + dependencies: + detect-libc: 2.0.1 + https-proxy-agent: 5.0.1 + make-dir: 3.1.0 + node-fetch: 2.6.12 + nopt: 5.0.0 + npmlog: 5.0.1 + rimraf: 3.0.2 + semver: 7.5.3 + tar: 6.1.15 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@npmcli/fs@1.1.1: + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.5.3 + dev: true + + /@npmcli/move-file@1.1.2: + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + dev: true + + /@npmcli/package-json@2.0.0: + resolution: {integrity: sha512-42jnZ6yl16GzjWSH7vtrmWyJDGVa/LXPdpN2rcUWolFjc9ON2N3uz0qdBbQACfmhuJZ2lbKYtmK5qx68ZPLHMA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + json-parse-even-better-errors: 2.3.1 + dev: true + + /@remix-run/router@1.7.0: + resolution: {integrity: sha512-Eu1V3kz3mV0wUpVTiFHuaT8UD1gj/0VnoFHQYX35xlslQUpe8CuYoKFn9d4WZFHm3yDywz6ALZuGdnUPKrNeAw==} + engines: {node: '>=14'} + dev: true + + /@remix-run/server-runtime@1.18.0: + resolution: {integrity: sha512-iiSKgGIWMkvf4ftnjGBmIJpgqxRwv8XQilAINapaYsx1zEM6egZGYE6WvaxLuRQSceZZNgLAYzL48TmK+DAU5g==} + engines: {node: '>=14.0.0'} + dependencies: + '@remix-run/router': 1.7.0 + '@types/cookie': 0.4.1 + '@web3-storage/multipart-parser': 1.0.0 + cookie: 0.4.2 + set-cookie-parser: 2.6.0 + source-map: 0.7.4 + dev: true + + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@sinclair/typebox@0.25.24: + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + dev: true + + /@sindresorhus/is@4.6.0: + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + dev: true + + /@szmarczak/http-timer@4.0.6: + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + dependencies: + defer-to-connect: 2.0.1 + dev: true + + /@tootallnate/once@1.1.2: + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + dev: true + + /@ts-morph/common@0.11.1: + resolution: {integrity: sha512-7hWZS0NRpEsNV8vWJzg7FEz6V8MaLNeJOmwmghqUXTpzk16V1LLZhdo+4QvE/+zv4cVci0OviuJFnqhEfoV3+g==} + dependencies: + fast-glob: 3.3.0 + minimatch: 3.1.2 + mkdirp: 1.0.4 + path-browserify: 1.0.1 + dev: true + + /@tsconfig/node10@1.0.9: + resolution: {integrity: sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==} + dev: true + + /@tsconfig/node12@1.0.11: + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + dev: true + + /@tsconfig/node14@1.0.3: + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + dev: true + + /@tsconfig/node16@1.0.4: + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + dev: true + + /@types/acorn@4.0.6: + resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /@types/cacheable-request@6.0.3: + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + dependencies: + '@types/http-cache-semantics': 4.0.1 + '@types/keyv': 3.1.4 + '@types/node': 20.3.3 + '@types/responselike': 1.0.0 + dev: true + + /@types/cookie@0.4.1: + resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} + dev: true + + /@types/debug@4.1.8: + resolution: {integrity: sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==} + dependencies: + '@types/ms': 0.7.31 + dev: true + + /@types/estree-jsx@0.0.1: + resolution: {integrity: sha512-gcLAYiMfQklDCPjQegGn0TBAn9it05ISEsEhlKQUddIk7o2XDokOcTN7HBO8tznM0D9dGezvHEfRZBfZf6me0A==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /@types/estree-jsx@1.0.0: + resolution: {integrity: sha512-3qvGd0z8F2ENTGr/GG1yViqfiKmRfrXVx5sJyHGFu3z7m5g5utCQtGp/g29JnjflhtQJBv1WDQukHiT58xPcYQ==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /@types/estree@1.0.1: + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + dev: true + + /@types/glob@7.2.0: + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.3.3 + dev: true + + /@types/hast@2.3.4: + resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/http-cache-semantics@4.0.1: + resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} + dev: true + + /@types/json-schema@7.0.12: + resolution: {integrity: sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==} + dev: true + + /@types/keyv@3.1.4: + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + dependencies: + '@types/node': 20.3.3 + dev: true + + /@types/mdast@3.0.11: + resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/mdurl@1.0.2: + resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==} + dev: true + + /@types/minimatch@5.1.2: + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true + + /@types/ms@0.7.31: + resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} + dev: true + + /@types/node-fetch@2.6.3: + resolution: {integrity: sha512-ETTL1mOEdq/sxUtgtOhKjyB2Irra4cjxksvcMUR5Zr4n+PxVhsCD9WS46oPbHL3et9Zde7CNRr+WUNlcHvsX+w==} + dependencies: + '@types/node': 20.3.3 + form-data: 3.0.1 + dev: true + + /@types/node@14.18.33: + resolution: {integrity: sha512-qelS/Ra6sacc4loe/3MSjXNL1dNQ/GjxNHVzuChwMfmk7HuycRLVQN2qNY3XahK+fZc5E2szqQSKUyAF0E+2bg==} + dev: true + + /@types/node@20.3.3: + resolution: {integrity: sha512-wheIYdr4NYML61AjC8MKj/2jrR/kDQri/CIpVoZwldwhnIrD/j9jIU5bJ8yBKuB2VhpFV7Ab6G2XkBjv9r9Zzw==} + dev: true + + /@types/responselike@1.0.0: + resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==} + dependencies: + '@types/node': 20.3.3 + dev: true + + /@types/unist@2.0.6: + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + dev: true + + /@types/web-bluetooth@0.0.17: + resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} + dev: true + + /@vanilla-extract/babel-plugin-debug-ids@1.0.3: + resolution: {integrity: sha512-vm4jYu1xhSa6ofQ9AhIpR3DkAp4c+eoR1Rpm8/TQI4DmWbmGbOjYRcqV0aWsfaIlNhN4kFuxFMKBNN9oG6iRzA==} + dependencies: + '@babel/core': 7.22.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@vanilla-extract/css@1.12.0: + resolution: {integrity: sha512-TEttZfnqTRtwgVYiBWQSGGUiVaYWReHp59DsavITEvh4TpJNifZFGhBznHx4wQFEsyio6xA513jps4tmqR6zmw==} + dependencies: + '@emotion/hash': 0.9.1 + '@vanilla-extract/private': 1.0.3 + ahocorasick: 1.0.2 + chalk: 4.1.2 + css-what: 6.1.0 + cssesc: 3.0.0 + csstype: 3.1.2 + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + media-query-parser: 2.0.2 + outdent: 0.8.0 + dev: true + + /@vanilla-extract/integration@6.2.1(@types/node@14.18.33): + resolution: {integrity: sha512-+xYJz07G7TFAMZGrOqArOsURG+xcYvqctujEkANjw2McCBvGEK505RxQqOuNiA9Mi9hgGdNp2JedSa94f3eoLg==} + dependencies: + '@babel/core': 7.22.5 + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.5) + '@vanilla-extract/babel-plugin-debug-ids': 1.0.3 + '@vanilla-extract/css': 1.12.0 + esbuild: 0.17.6 + eval: 0.1.6 + find-up: 5.0.0 + javascript-stringify: 2.1.0 + lodash: 4.17.21 + mlly: 1.4.0 + outdent: 0.8.0 + vite: 4.3.9(@types/node@14.18.33) + vite-node: 0.28.5(@types/node@14.18.33) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /@vanilla-extract/private@1.0.3: + resolution: {integrity: sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ==} + dev: true + + /@vercel/analytics@1.0.1: + resolution: {integrity: sha512-Ux0c9qUfkcPqng3vrR0GTrlQdqNJ2JREn/2ydrVuKwM3RtMfF2mWX31Ijqo1opSjNAq6rK76PwtANw6kl6TAow==} + dev: false + + /@vercel/build-utils@6.8.0: + resolution: {integrity: sha512-rGKTC1wCJeHvyEM4Td35M528XYPECcrb5xNF1k784BTVW4GicH6AQxr2YunfK+zkMBeR9WmG7fFAzEg38FLarw==} + dev: true + + /@vercel/error-utils@1.0.10: + resolution: {integrity: sha512-nsKy2sy+pjUWyKI1V/XXKspVzHMYgSalmj5+EsKWFXZbnNZicqxNtMR94J8Hs7SB4TQxh0s4KhczJtL59AVGMg==} + dev: true + + /@vercel/gatsby-plugin-vercel-analytics@1.0.10: + resolution: {integrity: sha512-v329WHdtIce+y7oAmaWRvEx59Xfo0FxlQqK4BJG0u6VWYoKWPaflohDAiehIZf/YHCRVb59ZxnzmMOcm/LR8YQ==} + dependencies: + '@babel/runtime': 7.12.1 + web-vitals: 0.2.4 + dev: true + + /@vercel/gatsby-plugin-vercel-builder@1.3.11: + resolution: {integrity: sha512-e+HY3OHC89NRTwcIlxZ3BdOnZ11xgAkA185Z+tkCLUNLowAigwdPxnelGcqSQaGTguwf+3nWxi8GUDYwtHi6/Q==} + dependencies: + '@sinclair/typebox': 0.25.24 + '@vercel/build-utils': 6.8.0 + '@vercel/node': 2.15.3 + '@vercel/routing-utils': 2.2.1 + esbuild: 0.14.47 + etag: 1.8.1 + fs-extra: 11.1.0 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + dev: true + + /@vercel/go@2.5.1: + resolution: {integrity: sha512-yZGzzGmVXt2Rsy1cR0EDbst0fMhdELQY8c3jXy6/FTWJFG1e/40JYksu+WiRCxRBp8e7zfcxMrv0dN8JWRmbPQ==} + dev: true + + /@vercel/hydrogen@0.0.64: + resolution: {integrity: sha512-1rzFB664G6Yzp7j4ezW9hvVjqnaU2BhyUdhchbsxtRuxkMpGgPBZKhjzRQHFvlmkz37XLC658T5Nb1P91b4sBw==} + dev: true + + /@vercel/next@3.8.8: + resolution: {integrity: sha512-h/TcVnrjnRrxkgTod80Wpy9Lo2k+DCpsNtRX+G0tJ8q8/WxMucQQ0dLv0t3J5vwmypowPzYzK5kKSfrewQVMxg==} + dev: true + + /@vercel/nft@0.22.5: + resolution: {integrity: sha512-mug57Wd1BL7GMj9gXMgMeKUjdqO0e4u+0QLPYMFE1rwdJ+55oPy6lp3nIBCS8gOvigT62UI4QKUL2sGqcoW4Hw==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@mapbox/node-pre-gyp': 1.0.10 + '@rollup/pluginutils': 4.2.1 + acorn: 8.9.0 + async-sema: 3.1.1 + bindings: 1.5.0 + estree-walker: 2.0.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + node-gyp-build: 4.6.0 + resolve-from: 5.0.0 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@vercel/node@2.15.3: + resolution: {integrity: sha512-kqti7lE6TT3sESXMsCm4lqtNXjyKr9P7+yhjDDL/TIzqfhqPLuiYmkiKYVNctnsdLrzDi9Cp2qaQA2a9/jpv1g==} + dependencies: + '@edge-runtime/node-utils': 2.0.3 + '@edge-runtime/primitives': 2.1.2 + '@edge-runtime/vm': 3.0.1 + '@types/node': 14.18.33 + '@types/node-fetch': 2.6.3 + '@vercel/build-utils': 6.8.0 + '@vercel/error-utils': 1.0.10 + '@vercel/static-config': 2.0.17 + async-listen: 3.0.0 + edge-runtime: 2.4.3 + esbuild: 0.14.47 + exit-hook: 2.2.1 + node-fetch: 2.6.9 + path-to-regexp: 6.2.1 + ts-morph: 12.0.0 + ts-node: 10.9.1(@types/node@14.18.33)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + dev: true + + /@vercel/python@3.1.60: + resolution: {integrity: sha512-1aYinyTfejS8Us+sOum+RQPYcre0vF3XoL7ohL170ZCcHA0l35qV0b1slGAmLt3pqaHKYy3g/nkzUhuR8XXIrQ==} + dev: true + + /@vercel/redwood@1.1.15: + resolution: {integrity: sha512-j0XaXe4ZpGVHG7XQSmZ3kza6s+ZtOBfRhnSxA70yCkrvPNN3tZgF3fevSKXizfL9fzVDd7Tdj++SCGWMdGfsyA==} + dependencies: + '@vercel/nft': 0.22.5 + '@vercel/routing-utils': 2.2.1 + semver: 6.1.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@vercel/remix-builder@1.8.15(@types/node@14.18.33): + resolution: {integrity: sha512-NV6YU2hwj1faLpldKEQmYWJ6+aGYUJLx2sCkWoEQy+WP9i4wHw0c3u+y+PfMlr3VBn1VIlDh1awf0NRXMcIEQg==} + dependencies: + '@remix-run/dev': /@vercel/remix-run-dev@1.18.0(@types/node@14.18.33) + '@vercel/build-utils': 6.8.0 + '@vercel/nft': 0.22.5 + '@vercel/static-config': 2.0.17 + path-to-regexp: 6.2.1 + semver: 7.3.8 + ts-morph: 12.0.0 + transitivePeerDependencies: + - '@remix-run/serve' + - '@types/node' + - bluebird + - bufferutil + - encoding + - less + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + - utf-8-validate + dev: true + + /@vercel/remix-run-dev@1.18.0(@types/node@14.18.33): + resolution: {integrity: sha512-5vGcc3OTBLZImKY0BMXDXDqdh0mjh4ZqptI9eRwXZ9O5AfGp4Ce7Q8tNldazBVOJMM4fGgLeXRIOTfuRDe5tDA==} + engines: {node: '>=14.0.0'} + hasBin: true + peerDependencies: + '@remix-run/serve': ^1.18.0 + peerDependenciesMeta: + '@remix-run/serve': + optional: true + dependencies: + '@babel/core': 7.22.5 + '@babel/generator': 7.22.5 + '@babel/parser': 7.22.5 + '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.5) + '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.5) + '@babel/preset-env': 7.22.5(@babel/core@7.22.5) + '@babel/preset-typescript': 7.22.5(@babel/core@7.22.5) + '@babel/traverse': 7.22.5 + '@babel/types': 7.22.5 + '@npmcli/package-json': 2.0.0 + '@remix-run/server-runtime': 1.18.0 + '@vanilla-extract/integration': 6.2.1(@types/node@14.18.33) + arg: 5.0.2 + cacache: 15.3.0 + chalk: 4.1.2 + chokidar: 3.5.3 + dotenv: 16.3.1 + esbuild: 0.17.6 + esbuild-plugins-node-modules-polyfill: 1.1.3(esbuild@0.17.6) + execa: 5.1.1 + exit-hook: 2.2.1 + express: 4.18.2 + fast-glob: 3.2.11 + fs-extra: 10.1.0 + get-port: 5.1.1 + gunzip-maybe: 1.4.2 + inquirer: 8.2.5 + jsesc: 3.0.2 + json5: 2.2.3 + lodash: 4.17.21 + lodash.debounce: 4.0.8 + minimatch: 9.0.2 + node-fetch: 2.6.12 + ora: 5.4.1 + picocolors: 1.0.0 + picomatch: 2.3.1 + pidtree: 0.6.0 + postcss: 8.4.24 + postcss-discard-duplicates: 5.1.0(postcss@8.4.24) + postcss-load-config: 4.0.1(postcss@8.4.24) + postcss-modules: 6.0.0(postcss@8.4.24) + prettier: 2.8.8 + pretty-ms: 7.0.1 + proxy-agent: 5.0.0 + react-refresh: 0.14.0 + recast: 0.21.5 + remark-frontmatter: 4.0.1 + remark-mdx-frontmatter: 1.1.1 + semver: 7.5.3 + sort-package-json: 1.57.0 + tar-fs: 2.1.1 + tsconfig-paths: 4.2.0 + ws: 7.5.9 + xdm: 2.1.0 + transitivePeerDependencies: + - '@types/node' + - bluebird + - bufferutil + - encoding + - less + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + - utf-8-validate + dev: true + + /@vercel/routing-utils@2.2.1: + resolution: {integrity: sha512-kzMZsvToDCDskNRZD71B9UAgstec7ujmlGH8cBEo6F/07VaFeji6GQdgd6Zwnrj+TvzQBggKoPQR64VkVY8Lzw==} + dependencies: + path-to-regexp: 6.1.0 + optionalDependencies: + ajv: 6.12.6 + dev: true + + /@vercel/ruby@1.3.76: + resolution: {integrity: sha512-J8I0B7wAn8piGoPhBroBfJWgMEJTMEL/2o8MCoCyWdaE7MRtpXhI10pj8IvcUvAECoGJ+SM1Pm+SvBqtbtZ5FQ==} + dev: true + + /@vercel/static-build@1.3.38: + resolution: {integrity: sha512-fm2msCefaFTOttvMoNp+/AOpwQLP79NbTZxDuEwE3CU4YUCNOrTaYTGj7ye99Qv+GcL66f4JyCrbBa7CKwmL8A==} + dependencies: + '@vercel/gatsby-plugin-vercel-analytics': 1.0.10 + '@vercel/gatsby-plugin-vercel-builder': 1.3.11 + transitivePeerDependencies: + - '@swc/core' + - '@swc/wasm' + - encoding + dev: true + + /@vercel/static-config@2.0.17: + resolution: {integrity: sha512-2f50OTVrN07x7pH+XNW0e7cj7T+Ufg+19+a2N3/XZBjQmV+FaMlmSLiaQ4tBxp2H8lWWHzENua7ZSSQPtRZ3/A==} + dependencies: + ajv: 8.6.3 + json-schema-to-ts: 1.6.4 + ts-morph: 12.0.0 + dev: true + + /@vitejs/plugin-vue@4.2.3(vite@4.3.9)(vue@3.3.4): + resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + dependencies: + vite: 4.3.9(@types/node@14.18.33) + vue: 3.3.4 + dev: true + + /@vue/compiler-core@3.3.4: + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + dependencies: + '@babel/parser': 7.22.5 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-dom@3.3.4: + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + dependencies: + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/compiler-sfc@3.3.4: + resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} + dependencies: + '@babel/parser': 7.22.5 + '@vue/compiler-core': 3.3.4 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-ssr': 3.3.4 + '@vue/reactivity-transform': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.0 + postcss: 8.4.24 + source-map-js: 1.0.2 + dev: true + + /@vue/compiler-ssr@3.3.4: + resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/devtools-api@6.5.0: + resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} + dev: true + + /@vue/reactivity-transform@3.3.4: + resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} + dependencies: + '@babel/parser': 7.22.5 + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.0 + dev: true + + /@vue/reactivity@3.3.4: + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + dependencies: + '@vue/shared': 3.3.4 + dev: true + + /@vue/runtime-core@3.3.4: + resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} + dependencies: + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + dev: true + + /@vue/runtime-dom@3.3.4: + resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} + dependencies: + '@vue/runtime-core': 3.3.4 + '@vue/shared': 3.3.4 + csstype: 3.1.2 + dev: true + + /@vue/server-renderer@3.3.4(vue@3.3.4): + resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} + peerDependencies: + vue: 3.3.4 + dependencies: + '@vue/compiler-ssr': 3.3.4 + '@vue/shared': 3.3.4 + vue: 3.3.4 + dev: true + + /@vue/shared@3.3.4: + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + dev: true + + /@vue/tsconfig@0.4.0: + resolution: {integrity: sha512-CPuIReonid9+zOG/CGTT05FXrPYATEqoDGNrEaqS4hwcw5BUNM2FguC0mOwJD4Jr16UpRVl9N0pY3P+srIbqmg==} + dev: true + + /@vueuse/core@10.2.1(vue@3.3.4): + resolution: {integrity: sha512-c441bfMbkAwTNwVRHQ0zdYZNETK//P84rC01aP2Uy/aRFCiie9NE/k9KdIXbno0eDYP5NPUuWv0aA/I4Unr/7w==} + dependencies: + '@types/web-bluetooth': 0.0.17 + '@vueuse/metadata': 10.2.1 + '@vueuse/shared': 10.2.1(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/integrations@10.2.1(focus-trap@7.4.3)(vue@3.3.4): + resolution: {integrity: sha512-FDP5lni+z9FjHE9H3xuvwSjoRV9U8jmDvJpmHPCBjUgPGYRynwb60eHWXCFJXLUtb4gSIHy0e+iaEbrKdalCkQ==} + peerDependencies: + async-validator: '*' + axios: '*' + change-case: '*' + drauu: '*' + focus-trap: '*' + fuse.js: '*' + idb-keyval: '*' + jwt-decode: '*' + nprogress: '*' + qrcode: '*' + sortablejs: '*' + universal-cookie: '*' + peerDependenciesMeta: + async-validator: + optional: true + axios: + optional: true + change-case: + optional: true + drauu: + optional: true + focus-trap: + optional: true + fuse.js: + optional: true + idb-keyval: + optional: true + jwt-decode: + optional: true + nprogress: + optional: true + qrcode: + optional: true + sortablejs: + optional: true + universal-cookie: + optional: true + dependencies: + '@vueuse/core': 10.2.1(vue@3.3.4) + '@vueuse/shared': 10.2.1(vue@3.3.4) + focus-trap: 7.4.3 + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@vueuse/metadata@10.2.1: + resolution: {integrity: sha512-3Gt68mY/i6bQvFqx7cuGBzrCCQu17OBaGWS5JdwISpMsHnMKKjC2FeB5OAfMcCQ0oINfADP3i9A4PPRo0peHdQ==} + dev: true + + /@vueuse/shared@10.2.1(vue@3.3.4): + resolution: {integrity: sha512-QWHq2bSuGptkcxx4f4M/fBYC3Y8d3M2UYyLsyzoPgEoVzJURQ0oJeWXu79OiLlBb8gTKkqe4mO85T/sf39mmiw==} + dependencies: + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: true + + /@web3-storage/multipart-parser@1.0.0: + resolution: {integrity: sha512-BEO6al7BYqcnfX15W2cnGR+Q566ACXAT9UQykORCWW80lmkpWsnEob6zJS1ZVBKsSJC8+7vJkHwlp+lXG1UCdw==} + dev: true + + /abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /acorn-jsx@5.3.2(acorn@8.9.0): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.9.0 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@8.9.0: + resolution: {integrity: sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ahocorasick@1.0.2: + resolution: {integrity: sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA==} + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + requiresBuild: true + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + optional: true + + /ajv@8.6.3: + resolution: {integrity: sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /algoliasearch@4.18.0: + resolution: {integrity: sha512-pCuVxC1SVcpc08ENH32T4sLKSyzoU7TkRIDBMwSLfIiW+fq4znOmWDkAygHZ6pRcO9I1UJdqlfgnV7TRj+MXrA==} + dependencies: + '@algolia/cache-browser-local-storage': 4.18.0 + '@algolia/cache-common': 4.18.0 + '@algolia/cache-in-memory': 4.18.0 + '@algolia/client-account': 4.18.0 + '@algolia/client-analytics': 4.18.0 + '@algolia/client-common': 4.18.0 + '@algolia/client-personalization': 4.18.0 + '@algolia/client-search': 4.18.0 + '@algolia/logger-common': 4.18.0 + '@algolia/logger-console': 4.18.0 + '@algolia/requester-browser-xhr': 4.18.0 + '@algolia/requester-common': 4.18.0 + '@algolia/requester-node-http': 4.18.0 + '@algolia/transporter': 4.18.0 + dev: true + + /ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.21.3 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-sequence-parser@1.1.0: + resolution: {integrity: sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ==} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: true + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: true + + /arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + dev: true + + /arg@5.0.2: + resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==} + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /ast-types@0.13.4: + resolution: {integrity: sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.0 + dev: true + + /ast-types@0.15.2: + resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.6.0 + dev: true + + /astring@1.8.6: + resolution: {integrity: sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg==} + hasBin: true + dev: true + + /async-listen@3.0.0: + resolution: {integrity: sha512-V+SsTpDqkrWTimiotsyl33ePSjA5/KrithwupuvJ6ztsqPvGv6ge4OredFhPffVXiLN/QUWvE0XcqJaYgt6fOg==} + engines: {node: '>= 14'} + dev: true + + /async-sema@3.1.1: + resolution: {integrity: sha512-tLRNUXati5MFePdAk8dw7Qt7DpxPB60ofAgn8WRhW6a2rcimZnYBP9oxHiv0OHy+Wz7kPMG+t4LGdt31+4EmGg==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + dev: true + + /babel-plugin-polyfill-corejs2@0.4.3(@babel/core@7.22.5): + resolution: {integrity: sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.22.5 + '@babel/core': 7.22.5 + '@babel/helper-define-polyfill-provider': 0.4.0(@babel/core@7.22.5) + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.8.1(@babel/core@7.22.5): + resolution: {integrity: sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-define-polyfill-provider': 0.4.0(@babel/core@7.22.5) + core-js-compat: 3.31.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.5.0(@babel/core@7.22.5): + resolution: {integrity: sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.22.5 + '@babel/helper-define-polyfill-provider': 0.4.0(@babel/core@7.22.5) + transitivePeerDependencies: + - supports-color + dev: true + + /bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /body-scroll-lock@4.0.0-beta.0: + resolution: {integrity: sha512-a7tP5+0Mw3YlUJcGAKUqIBkYYGlYxk2fnCasq/FUph1hadxlTRjF+gAcZksxANnaMnALjxEddmSi/H3OR8ugcQ==} + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + dependencies: + pako: 0.2.9 + dev: true + + /browserslist@4.21.9: + resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001511 + electron-to-chromium: 1.4.447 + node-releases: 2.0.12 + update-browserslist-db: 1.0.11(browserslist@4.21.9) + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.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: 8.0.1 + tar: 6.1.15 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + dev: true + + /cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + dev: true + + /cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.2 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /caniuse-lite@1.0.30001511: + resolution: {integrity: sha512-NaWPJawcoedlghN4P7bDNeADD7K+rZaY6V8ZcME7PkEZo/nfOg+lnrUgRWiKbNxcQ4/toFKSxnS4WdbyPZnKkw==} + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + dev: true + + /character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + dev: true + + /character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + dev: true + + /character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + dev: true + + /chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + + /cli-spinners@2.9.0: + resolution: {integrity: sha512-4/aL9X3Wh0yiMQlE+eeRhWP6vclO3QRtw1JHKIT0FFUs5FjpFmESqtMvYZ0+lbzBw900b95mS0hohy+qn2VK/g==} + engines: {node: '>=6'} + dev: true + + /cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + dev: true + + /clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + dependencies: + mimic-response: 1.0.1 + dev: true + + /clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + dev: true + + /code-block-writer@10.1.1: + resolution: {integrity: sha512-67ueh2IRGst/51p0n6FvPrnRjAGHY5F8xdjkgrYE7DDzpJe6qA07RYQ9VcoUeo5ATOjSOiWpSL3SWBRRbempMw==} + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + dev: true + + /comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: true + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: true + + /convert-hrtime@3.0.0: + resolution: {integrity: sha512-7V+KqSvMiHp8yWDuwfww06XleMWVVB9b9tURBx+G7UTADuo5hYPuowKloz4OzOqbPezxgo+fdQ1522WzPG4OeA==} + engines: {node: '>=8'} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + dev: true + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /core-js-compat@3.31.0: + resolution: {integrity: sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw==} + dependencies: + browserslist: 4.21.9 + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: true + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + dev: true + + /data-uri-to-buffer@3.0.1: + resolution: {integrity: sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og==} + engines: {node: '>= 6'} + dev: true + + /deasync@0.1.28: + resolution: {integrity: sha512-QqLF6inIDwiATrfROIyQtwOQxjZuek13WRYZ7donU5wJPLoP67MnYxA6QtqdvdBy2mMqv5m3UefBVdJjvevOYg==} + engines: {node: '>=0.11.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + node-addon-api: 1.7.2 + dev: true + optional: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + dependencies: + character-entities: 2.0.2 + dev: true + + /decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + dependencies: + mimic-response: 3.1.0 + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + dependencies: + clone: 1.0.4 + dev: true + + /defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + dev: true + + /degenerator@3.0.4: + resolution: {integrity: sha512-Z66uPeBfHZAHVmue3HPfyKu2Q0rC2cRxbTOsvmU/po5fvvcx27W4mIu9n0PUlQih4oUYvcG1BsbtVv8x7KDOSw==} + engines: {node: '>= 6'} + dependencies: + ast-types: 0.13.4 + escodegen: 1.14.3 + esprima: 4.0.1 + vm2: 3.9.19 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + dev: true + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: true + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detect-libc@2.0.1: + resolution: {integrity: sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==} + engines: {node: '>=8'} + dev: true + + /detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + dev: true + + /diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + dev: true + + /diff@5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /dotenv@16.3.1: + resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + engines: {node: '>=12'} + dev: true + + /duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.1 + dev: true + + /edge-runtime@2.4.3: + resolution: {integrity: sha512-Amv/P+OJhxopvoVXFr7UXAKheBpdLeCcdR5Vw4GSdNFDWVny9sioQbczjEKPLER5WsMXl17P+llS011Xftducw==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@edge-runtime/format': 2.1.0 + '@edge-runtime/vm': 3.0.3 + async-listen: 3.0.0 + mri: 1.2.0 + picocolors: 1.0.0 + pretty-bytes: 5.6.0 + pretty-ms: 7.0.1 + signal-exit: 4.0.2 + time-span: 4.0.0 + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /electron-to-chromium@1.4.447: + resolution: {integrity: sha512-sxX0LXh+uL41hSJsujAN86PjhrV/6c79XmpY0TvjZStV6VxIgarf8SRkUoUTuYmFcZQTemsoqo8qXOGw5npWfw==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + dev: true + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /esbuild-android-64@0.14.47: + resolution: {integrity: sha512-R13Bd9+tqLVFndncMHssZrPWe6/0Kpv2/dt4aA69soX4PRxlzsVpCvoJeFE8sOEoeVEiBkI0myjlkDodXlHa0g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-android-arm64@0.14.47: + resolution: {integrity: sha512-OkwOjj7ts4lBp/TL6hdd8HftIzOy/pdtbrNA4+0oVWgGG64HrdVzAF5gxtJufAPOsEjkyh1oIYvKAUinKKQRSQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-64@0.14.47: + resolution: {integrity: sha512-R6oaW0y5/u6Eccti/TS6c/2c1xYTb1izwK3gajJwi4vIfNs1s8B1dQzI1UiC9T61YovOQVuePDcfqHLT3mUZJA==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-darwin-arm64@0.14.47: + resolution: {integrity: sha512-seCmearlQyvdvM/noz1L9+qblC5vcBrhUaOoLEDDoLInF/VQ9IkobGiLlyTPYP5dW1YD4LXhtBgOyevoIHGGnw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-64@0.14.47: + resolution: {integrity: sha512-ZH8K2Q8/Ux5kXXvQMDsJcxvkIwut69KVrYQhza/ptkW50DC089bCVrJZZ3sKzIoOx+YPTrmsZvqeZERjyYrlvQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-freebsd-arm64@0.14.47: + resolution: {integrity: sha512-ZJMQAJQsIOhn3XTm7MPQfCzEu5b9STNC+s90zMWe2afy9EwnHV7Ov7ohEMv2lyWlc2pjqLW8QJnz2r0KZmeAEQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-32@0.14.47: + resolution: {integrity: sha512-FxZOCKoEDPRYvq300lsWCTv1kcHgiiZfNrPtEhFAiqD7QZaXrad8LxyJ8fXGcWzIFzRiYZVtB3ttvITBvAFhKw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-64@0.14.47: + resolution: {integrity: sha512-nFNOk9vWVfvWYF9YNYksZptgQAdstnDCMtR6m42l5Wfugbzu11VpMCY9XrD4yFxvPo9zmzcoUL/88y0lfJZJJw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm64@0.14.47: + resolution: {integrity: sha512-ywfme6HVrhWcevzmsufjd4iT3PxTfCX9HOdxA7Hd+/ZM23Y9nXeb+vG6AyA6jgq/JovkcqRHcL9XwRNpWG6XRw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-arm@0.14.47: + resolution: {integrity: sha512-ZGE1Bqg/gPRXrBpgpvH81tQHpiaGxa8c9Rx/XOylkIl2ypLuOcawXEAo8ls+5DFCcRGt/o3sV+PzpAFZobOsmA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-mips64le@0.14.47: + resolution: {integrity: sha512-mg3D8YndZ1LvUiEdDYR3OsmeyAew4MA/dvaEJxvyygahWmpv1SlEEnhEZlhPokjsUMfRagzsEF/d/2XF+kTQGg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-ppc64le@0.14.47: + resolution: {integrity: sha512-WER+f3+szmnZiWoK6AsrTKGoJoErG2LlauSmk73LEZFQ/iWC+KhhDsOkn1xBUpzXWsxN9THmQFltLoaFEH8F8w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-riscv64@0.14.47: + resolution: {integrity: sha512-1fI6bP3A3rvI9BsaaXbMoaOjLE3lVkJtLxsgLHqlBhLlBVY7UqffWBvkrX/9zfPhhVMd9ZRFiaqXnB1T7BsL2g==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-linux-s390x@0.14.47: + resolution: {integrity: sha512-eZrWzy0xFAhki1CWRGnhsHVz7IlSKX6yT2tj2Eg8lhAwlRE5E96Hsb0M1mPSE1dHGpt1QVwwVivXIAacF/G6mw==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /esbuild-netbsd-64@0.14.47: + resolution: {integrity: sha512-Qjdjr+KQQVH5Q2Q1r6HBYswFTToPpss3gqCiSw2Fpq/ua8+eXSQyAMG+UvULPqXceOwpnPo4smyZyHdlkcPppQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-openbsd-64@0.14.47: + resolution: {integrity: sha512-QpgN8ofL7B9z8g5zZqJE+eFvD1LehRlxr25PBkjyyasakm4599iroUpaj96rdqRlO2ShuyqwJdr+oNqWwTUmQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /esbuild-plugins-node-modules-polyfill@1.1.3(esbuild@0.17.6): + resolution: {integrity: sha512-h5gubIqBcAPQ3052rDxjHh8XAM5pSMGHlTNpDRt6GHsIX5V7eKjlK8R9CMpfqX76nQQG5A9o3ZHfnZDlf7WG4g==} + engines: {node: '>=14.0.0'} + peerDependencies: + esbuild: ^0.14.0 || ^0.15.0 || ^0.16.0 || ^0.17.0 || ^0.18.0 + dependencies: + '@jspm/core': 2.0.1 + esbuild: 0.17.6 + local-pkg: 0.4.3 + resolve.exports: 2.0.2 + dev: true + + /esbuild-sunos-64@0.14.47: + resolution: {integrity: sha512-uOeSgLUwukLioAJOiGYm3kNl+1wJjgJA8R671GYgcPgCx7QR73zfvYqXFFcIO93/nBdIbt5hd8RItqbbf3HtAQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-32@0.14.47: + resolution: {integrity: sha512-H0fWsLTp2WBfKLBgwYT4OTfFly4Im/8B5f3ojDv1Kx//kiubVY0IQunP2Koc/fr/0wI7hj3IiBDbSrmKlrNgLQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-64@0.14.47: + resolution: {integrity: sha512-/Pk5jIEH34T68r8PweKRi77W49KwanZ8X6lr3vDAtOlH5EumPE4pBHqkCUdELanvsT14yMXLQ/C/8XPi1pAtkQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild-windows-arm64@0.14.47: + resolution: {integrity: sha512-HFSW2lnp62fl86/qPQlqw6asIwCnEsEoNIL1h2uVMgakddf+vUuMcCbtUY1i8sst7KkgHrVKCJQB33YhhOweCQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /esbuild@0.14.47: + resolution: {integrity: sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + esbuild-android-64: 0.14.47 + esbuild-android-arm64: 0.14.47 + esbuild-darwin-64: 0.14.47 + esbuild-darwin-arm64: 0.14.47 + esbuild-freebsd-64: 0.14.47 + esbuild-freebsd-arm64: 0.14.47 + esbuild-linux-32: 0.14.47 + esbuild-linux-64: 0.14.47 + esbuild-linux-arm: 0.14.47 + esbuild-linux-arm64: 0.14.47 + esbuild-linux-mips64le: 0.14.47 + esbuild-linux-ppc64le: 0.14.47 + esbuild-linux-riscv64: 0.14.47 + esbuild-linux-s390x: 0.14.47 + esbuild-netbsd-64: 0.14.47 + esbuild-openbsd-64: 0.14.47 + esbuild-sunos-64: 0.14.47 + esbuild-windows-32: 0.14.47 + esbuild-windows-64: 0.14.47 + esbuild-windows-arm64: 0.14.47 + dev: true + + /esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + /esbuild@0.17.6: + resolution: {integrity: sha512-TKFRp9TxrJDdRWfSsSERKEovm6v30iHnrjlcGhLBOtReE28Yp1VSBRfO3GTaOFMoxsNerx4TjrhzSuma9ha83Q==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.6 + '@esbuild/android-arm64': 0.17.6 + '@esbuild/android-x64': 0.17.6 + '@esbuild/darwin-arm64': 0.17.6 + '@esbuild/darwin-x64': 0.17.6 + '@esbuild/freebsd-arm64': 0.17.6 + '@esbuild/freebsd-x64': 0.17.6 + '@esbuild/linux-arm': 0.17.6 + '@esbuild/linux-arm64': 0.17.6 + '@esbuild/linux-ia32': 0.17.6 + '@esbuild/linux-loong64': 0.17.6 + '@esbuild/linux-mips64el': 0.17.6 + '@esbuild/linux-ppc64': 0.17.6 + '@esbuild/linux-riscv64': 0.17.6 + '@esbuild/linux-s390x': 0.17.6 + '@esbuild/linux-x64': 0.17.6 + '@esbuild/netbsd-x64': 0.17.6 + '@esbuild/openbsd-x64': 0.17.6 + '@esbuild/sunos-x64': 0.17.6 + '@esbuild/win32-arm64': 0.17.6 + '@esbuild/win32-ia32': 0.17.6 + '@esbuild/win32-x64': 0.17.6 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escodegen@1.14.3: + resolution: {integrity: sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==} + engines: {node: '>=4.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 4.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estree-util-attach-comments@2.1.1: + resolution: {integrity: sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /estree-util-build-jsx@2.2.2: + resolution: {integrity: sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==} + dependencies: + '@types/estree-jsx': 1.0.0 + estree-util-is-identifier-name: 2.1.0 + estree-walker: 3.0.3 + dev: true + + /estree-util-is-identifier-name@1.1.0: + resolution: {integrity: sha512-OVJZ3fGGt9By77Ix9NhaRbzfbDV/2rx9EP7YIDJTmsZSEc5kYn2vWcNccYyahJL2uAQZK2a5Or2i0wtIKTPoRQ==} + dev: true + + /estree-util-is-identifier-name@2.1.0: + resolution: {integrity: sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==} + dev: true + + /estree-util-value-to-estree@1.3.0: + resolution: {integrity: sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==} + engines: {node: '>=12.0.0'} + dependencies: + is-plain-obj: 3.0.0 + dev: true + + /estree-util-visit@1.2.1: + resolution: {integrity: sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/unist': 2.0.6 + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + dev: true + + /estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /eval@0.1.6: + resolution: {integrity: sha512-o0XUw+5OGkXw4pJZzQoXUk+H87DHuC+7ZE//oSrRGtatTmr12oTnLfg6QOq9DyTt0c/p4TwzgmkKrBzWTSizyQ==} + engines: {node: '>= 0.8'} + dependencies: + require-like: 0.1.2 + dev: true + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /exit-hook@2.2.1: + resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} + engines: {node: '>=6'} + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-glob@3.2.11: + resolution: {integrity: sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-glob@3.3.0: + resolution: {integrity: sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + optional: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fault@2.0.1: + resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==} + dependencies: + format: 0.2.2 + dev: true + + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + + /file-uri-to-path@2.0.0: + resolution: {integrity: sha512-hjPFI8oE/2iQPVe4gbrJ73Pp+Xfub2+WI2LlXDbsaJBwT5wuMh35WNWVYYTpnz895shtwfyutMFLFywpQAFdLg==} + engines: {node: '>= 6'} + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + 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 + transitivePeerDependencies: + - supports-color + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /focus-trap@7.4.3: + resolution: {integrity: sha512-BgSSbK4GPnS2VbtZ50VtOv1Sti6DIkj3+LkVjiWMNjLeAp1SH1UlLx3ULu/DCu4vq5R4/uvTm+zrvsMsuYmGLg==} + dependencies: + tabbable: 6.2.0 + dev: true + + /form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /format@0.2.2: + resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} + engines: {node: '>=0.4.x'} + dev: true + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-extra@11.1.0: + resolution: {integrity: sha512-0rcTq621PD5jM/e0a3EJoGC/1TC5ZBCERW82LQuwfGnCa1V8w7dpYH1yNu+SLb6E5dkeCBzKEyLGlFrnr+dUyw==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + dev: true + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /ftp@0.3.10: + resolution: {integrity: sha512-faFVML1aBx2UoDStmLwv2Wptt4vw5x03xxX172nhA5Y5HBshW5JweqQ2W4xL4dezQTG8inJsuYcpPHHU3X5OTQ==} + engines: {node: '>=0.8.0'} + dependencies: + readable-stream: 1.1.14 + xregexp: 2.0.0 + dev: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + + /generic-names@4.0.0: + resolution: {integrity: sha512-ySFolZQfw9FoDb3ed9d80Cm9f0+r7qj+HJkWjeD9RBfpxEVTlVhol+gvaQB/78WbwYfbnNh8nWHHBSlg072y6A==} + dependencies: + loader-utils: 3.2.1 + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + + /get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + dev: true + + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-uri@3.0.2: + resolution: {integrity: sha512-+5s0SJbGoyiJTZZ2JTpFPLMPSch72KEqGOTvQsBqg0RBWvwhWUSYZFAtz3TPW0GXJuLBJPts1E241iHg+VRfhg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + data-uri-to-buffer: 3.0.1 + debug: 4.3.4 + file-uri-to-path: 2.0.0 + fs-extra: 8.1.0 + ftp: 0.3.10 + transitivePeerDependencies: + - supports-color + dev: true + + /git-hooks-list@1.0.3: + resolution: {integrity: sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==} + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globby@10.0.0: + resolution: {integrity: sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==} + engines: {node: '>=8'} + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.0 + glob: 7.2.3 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.0 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true + dependencies: + browserify-zlib: 0.1.4 + is-deflate: 1.0.0 + is-gzip: 1.0.0 + peek-stream: 1.1.3 + pumpify: 1.5.1 + through2: 2.0.5 + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hast-util-to-estree@2.3.3: + resolution: {integrity: sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==} + dependencies: + '@types/estree': 1.0.1 + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/unist': 2.0.6 + comma-separated-tokens: 2.0.3 + estree-util-attach-comments: 2.1.1 + estree-util-is-identifier-name: 2.1.0 + hast-util-whitespace: 2.0.1 + mdast-util-mdx-expression: 1.3.2 + mdast-util-mdxjs-esm: 1.3.1 + property-information: 6.2.0 + space-separated-tokens: 2.0.2 + style-to-object: 0.4.1 + unist-util-position: 4.0.4 + zwitch: 2.0.4 + transitivePeerDependencies: + - supports-color + dev: true + + /hast-util-whitespace@2.0.1: + resolution: {integrity: sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==} + dev: true + + /http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /icss-utils@5.1.0(postcss@8.4.24): + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.24 + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + dev: true + + /inquirer@8.2.5: + resolution: {integrity: sha512-QAgPDQMEgrDssk1XiwwHoOGYF9BAbUcc1+j+FhEvaOt8/cKRqyLn0U5qA6F74fGhTMGxf92pOvPBeh29jQJDTQ==} + engines: {node: '>=12.0.0'} + dependencies: + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + external-editor: 3.1.0 + figures: 3.2.0 + lodash: 4.17.21 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.1 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + + /ip@1.1.8: + resolution: {integrity: sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==} + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + dev: true + + /is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + dev: true + + /is-core-module@2.12.1: + resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + dependencies: + has: 1.0.3 + dev: true + + /is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + dev: true + + /is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + dev: true + + /is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + dev: true + + /is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + dev: true + + /is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + dev: true + + /is-reference@3.0.1: + resolution: {integrity: sha512-baJJdQLiYaJdvFbJqXrcGv3WU3QCzBlUcI5QhbesIm6/xPsvmO+2CDoi/GMOFBQEQm+PXkwOPrp9KK5ozZsp2w==} + dependencies: + '@types/estree': 1.0.1 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + + /isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /javascript-stringify@2.1.0: + resolution: {integrity: sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg==} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-to-ts@1.6.4: + resolution: {integrity: sha512-pR4yQ9DHz6itqswtHCm26mw45FSNfQ9rEQjosaZErhn5J3J2sIViQiz8rDaezjKAhFGpmsoczYVBgGHzFw/stA==} + dependencies: + '@types/json-schema': 7.0.12 + ts-toolbelt: 6.15.5 + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + optional: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /keyv@4.5.2: + resolution: {integrity: sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==} + dependencies: + json-buffer: 3.0.1 + dev: true + + /kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + dev: true + + /levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + + /lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + dev: true + + /loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + dev: true + + /loader-utils@3.2.1: + resolution: {integrity: sha512-ZvFw1KWS3GVyYBYb7qkmRM/WwL2TQQBxgCK62rlvm4WpVQ23Nb4tYjApUlfjrEGvOs7KHEsmyUn75OHZrJMWPw==} + engines: {node: '>= 12.13.0'} + dev: true + + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + dev: true + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + dev: true + + /lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /magic-string@0.30.0: + resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + dev: true + + /mark.js@8.11.1: + resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==} + dev: true + + /markdown-extensions@1.1.1: + resolution: {integrity: sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==} + engines: {node: '>=0.10.0'} + dev: true + + /mdast-util-definitions@5.1.2: + resolution: {integrity: sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==} + dependencies: + '@types/mdast': 3.0.11 + '@types/unist': 2.0.6 + unist-util-visit: 4.1.2 + dev: true + + /mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + dependencies: + '@types/mdast': 3.0.11 + '@types/unist': 2.0.6 + decode-named-character-reference: 1.0.2 + mdast-util-to-string: 3.2.0 + micromark: 3.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-decode-string: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-stringify-position: 3.0.3 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-frontmatter@1.0.1: + resolution: {integrity: sha512-JjA2OjxRqAa8wEG8hloD0uTU0kdn8kbtOWpPP94NBkfAlbxn4S8gCGf/9DwFtEeGPXrDcNXdiDjVaRdUFqYokw==} + dependencies: + '@types/mdast': 3.0.11 + mdast-util-to-markdown: 1.5.0 + micromark-extension-frontmatter: 1.1.1 + dev: true + + /mdast-util-mdx-expression@1.3.2: + resolution: {integrity: sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/mdast': 3.0.11 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-mdx-jsx@1.2.0: + resolution: {integrity: sha512-5+ot/kfxYd3ChgEMwsMUO71oAfYjyRI3pADEK4I7xTmWLGQ8Y7ghm1CG36zUoUvDPxMlIYwQV/9DYHAUWdG4dA==} + dependencies: + '@types/estree-jsx': 0.0.1 + '@types/mdast': 3.0.11 + mdast-util-to-markdown: 1.5.0 + parse-entities: 4.0.1 + stringify-entities: 4.0.3 + unist-util-remove-position: 4.0.2 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + dev: true + + /mdast-util-mdx@1.1.0: + resolution: {integrity: sha512-leKb9uG7laXdyFlTleYV4ZEaCpsxeU1LlkkR/xp35pgKrfV1Y0fNCuOw9vaRc2a9YDpH22wd145Wt7UY5yzeZw==} + dependencies: + mdast-util-mdx-expression: 1.3.2 + mdast-util-mdx-jsx: 1.2.0 + mdast-util-mdxjs-esm: 1.3.1 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-mdxjs-esm@1.3.1: + resolution: {integrity: sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==} + dependencies: + '@types/estree-jsx': 1.0.0 + '@types/hast': 2.3.4 + '@types/mdast': 3.0.11 + mdast-util-from-markdown: 1.3.1 + mdast-util-to-markdown: 1.5.0 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-phrasing@3.0.1: + resolution: {integrity: sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==} + dependencies: + '@types/mdast': 3.0.11 + unist-util-is: 5.2.1 + dev: true + + /mdast-util-to-hast@11.3.0: + resolution: {integrity: sha512-4o3Cli3hXPmm1LhB+6rqhfsIUBjnKFlIUZvudaermXB+4/KONdd/W4saWWkC+LBLbPMqhFSSTSRgafHsT5fVJw==} + dependencies: + '@types/hast': 2.3.4 + '@types/mdast': 3.0.11 + '@types/mdurl': 1.0.2 + mdast-util-definitions: 5.1.2 + mdurl: 1.0.1 + unist-builder: 3.0.1 + unist-util-generated: 2.0.1 + unist-util-position: 4.0.4 + unist-util-visit: 4.1.2 + dev: true + + /mdast-util-to-markdown@1.5.0: + resolution: {integrity: sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==} + dependencies: + '@types/mdast': 3.0.11 + '@types/unist': 2.0.6 + longest-streak: 3.1.0 + mdast-util-phrasing: 3.0.1 + mdast-util-to-string: 3.2.0 + micromark-util-decode-string: 1.1.0 + unist-util-visit: 4.1.2 + zwitch: 2.0.4 + dev: true + + /mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + dependencies: + '@types/mdast': 3.0.11 + dev: true + + /mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + dev: true + + /media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + dependencies: + '@babel/runtime': 7.22.5 + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /medium-zoom@1.0.8: + resolution: {integrity: sha512-CjFVuFq/IfrdqesAXfg+hzlDKu6A2n80ZIq0Kl9kWjoHh9j1N9Uvk5X0/MmN0hOfm5F9YBswlClhcwnmtwz7gA==} + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-factory-destination: 1.1.0 + micromark-factory-label: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-factory-title: 1.1.0 + micromark-factory-whitespace: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-html-tag-name: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: true + + /micromark-extension-frontmatter@1.1.1: + resolution: {integrity: sha512-m2UH9a7n3W8VAH9JO9y01APpPKmNNNs71P0RbknEmYSaZU5Ghogv38BYO94AI5Xw6OYfxZRdHZZ2nYjs/Z+SZQ==} + dependencies: + fault: 2.0.1 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-extension-mdx-expression@1.0.8: + resolution: {integrity: sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==} + dependencies: + '@types/estree': 1.0.1 + micromark-factory-mdx-expression: 1.0.9 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: true + + /micromark-extension-mdx-jsx@1.0.5: + resolution: {integrity: sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.1 + estree-util-is-identifier-name: 2.1.0 + micromark-factory-mdx-expression: 1.0.9 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + vfile-message: 3.1.4 + dev: true + + /micromark-extension-mdx-md@1.0.1: + resolution: {integrity: sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==} + dependencies: + micromark-util-types: 1.1.0 + dev: true + + /micromark-extension-mdxjs-esm@1.0.5: + resolution: {integrity: sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==} + dependencies: + '@types/estree': 1.0.1 + micromark-core-commonmark: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-position-from-estree: 1.1.2 + uvu: 0.5.6 + vfile-message: 3.1.4 + dev: true + + /micromark-extension-mdxjs@1.0.1: + resolution: {integrity: sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==} + dependencies: + acorn: 8.9.0 + acorn-jsx: 5.3.2(acorn@8.9.0) + micromark-extension-mdx-expression: 1.0.8 + micromark-extension-mdx-jsx: 1.0.5 + micromark-extension-mdx-md: 1.0.1 + micromark-extension-mdxjs-esm: 1.0.5 + micromark-util-combine-extensions: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: true + + /micromark-factory-mdx-expression@1.0.9: + resolution: {integrity: sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==} + dependencies: + '@types/estree': 1.0.1 + micromark-util-character: 1.2.0 + micromark-util-events-to-acorn: 1.2.3 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-position-from-estree: 1.1.2 + uvu: 0.5.6 + vfile-message: 3.1.4 + dev: true + + /micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: true + + /micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-types: 1.1.0 + dev: true + + /micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: true + + /micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 1.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-symbol: 1.1.0 + dev: true + + /micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + dev: true + + /micromark-util-events-to-acorn@1.2.3: + resolution: {integrity: sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==} + dependencies: + '@types/acorn': 4.0.6 + '@types/estree': 1.0.1 + '@types/unist': 2.0.6 + estree-util-visit: 1.2.1 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + vfile-message: 3.1.4 + dev: true + + /micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + dev: true + + /micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + dependencies: + micromark-util-symbol: 1.1.0 + dev: true + + /micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + dependencies: + micromark-util-types: 1.1.0 + dev: true + + /micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + dependencies: + micromark-util-character: 1.2.0 + micromark-util-encode: 1.1.0 + micromark-util-symbol: 1.1.0 + dev: true + + /micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + dev: true + + /micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + dev: true + + /micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + dev: true + + /micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + dependencies: + '@types/debug': 4.1.8 + debug: 4.3.4 + decode-named-character-reference: 1.0.2 + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-combine-extensions: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-encode: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + dev: true + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + dev: true + + /mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@9.0.2: + resolution: {integrity: sha512-PZOT9g5v2ojiTL7r1xF6plNHLtOeTpSlDI007As2NlA2aYBMfVom17yqa6QzhmDP8QOhn7LjHTg7DFCVSSa6yg==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass-flush@1.0.5: + resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + dependencies: + minipass: 3.3.6 + dev: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: true + + /minisearch@6.1.0: + resolution: {integrity: sha512-PNxA/X8pWk+TiqPbsoIYH0GQ5Di7m6326/lwU/S4mlo4wGQddIcf/V//1f9TB0V4j59b57b+HZxt8h3iMROGvg==} + dev: true + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mlly@1.4.0: + resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} + dependencies: + acorn: 8.9.0 + pathe: 1.1.1 + pkg-types: 1.0.3 + ufo: 1.1.2 + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + dev: true + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /netmask@2.0.2: + resolution: {integrity: sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==} + engines: {node: '>= 0.4.0'} + dev: true + + /node-addon-api@1.7.2: + resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + dev: true + optional: true + + /node-fetch@2.6.12: + resolution: {integrity: sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-fetch@2.6.9: + resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-gyp-build@4.6.0: + resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==} + hasBin: true + dev: true + + /node-releases@2.0.12: + resolution: {integrity: sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ==} + dev: true + + /nopt@5.0.0: + resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} + engines: {node: '>=6'} + hasBin: true + dependencies: + abbrev: 1.1.1 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.3 + dev: true + + /ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.0 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + dev: true + + /os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /outdent@0.8.0: + resolution: {integrity: sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A==} + dev: true + + /p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /pac-proxy-agent@5.0.0: + resolution: {integrity: sha512-CcFG3ZtnxO8McDigozwE3AqAw15zDvGH+OjXO4kzf7IkEKkQ4gxQ+3sdF50WmhQ4P/bVusXcqNE2S3XrNURwzQ==} + engines: {node: '>= 8'} + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.3.4 + get-uri: 3.0.2 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + pac-resolver: 5.0.1 + raw-body: 2.5.2 + socks-proxy-agent: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /pac-resolver@5.0.1: + resolution: {integrity: sha512-cy7u00ko2KVgBAjuhevqpPeHIkCIqPe1v24cydhWjmeuzaBfmUWFCZJ1iAh5TuVzVZoUzXIW7K8sMYOZ84uZ9Q==} + engines: {node: '>= 8'} + dependencies: + degenerator: 3.0.4 + ip: 1.1.8 + netmask: 2.0.2 + dev: true + + /pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + dev: true + + /parse-entities@4.0.1: + resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + dependencies: + '@types/unist': 2.0.6 + character-entities: 2.0.2 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.0.2 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + dev: true + + /parse-ms@2.1.0: + resolution: {integrity: sha512-kHt7kzLoS9VBZfUsiKjv43mr91ea+U05EyKkEtqp7vNbHxmaVuEqN7XxeEVnGrMtYOAxGrDElSi96K7EgO1zCA==} + engines: {node: '>=6'} + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /path-to-regexp@6.1.0: + resolution: {integrity: sha512-h9DqehX3zZZDCEm+xbfU0ZmwCGFCAAraPJWMXJ4+v32NjZJilVg3k1TcKsRgIb8IQ/izZSaydDc1OhJCZvs2Dw==} + dev: true + + /path-to-regexp@6.2.1: + resolution: {integrity: sha512-JLyh7xT1kizaEvcaXOQwOc2/Yhw6KZOvPf1S8401UyLk86CU79LN3vl7ztXGm/pZ+YjoyAJ4rxmHwbkBXJX+yw==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pathe@1.1.1: + resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} + dev: true + + /peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + dependencies: + buffer-from: 1.1.2 + duplexify: 3.7.1 + through2: 2.0.5 + dev: true + + /periscopic@3.1.0: + resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} + dependencies: + '@types/estree': 1.0.1 + estree-walker: 3.0.3 + is-reference: 3.0.1 + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + dev: true + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pidtree@0.6.0: + resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.4.0 + pathe: 1.1.1 + dev: true + + /postcss-discard-duplicates@5.1.0(postcss@8.4.24): + resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + dependencies: + postcss: 8.4.24 + dev: true + + /postcss-load-config@4.0.1(postcss@8.4.24): + resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} + engines: {node: '>= 14'} + peerDependencies: + postcss: '>=8.0.9' + ts-node: '>=9.0.0' + peerDependenciesMeta: + postcss: + optional: true + ts-node: + optional: true + dependencies: + lilconfig: 2.1.0 + postcss: 8.4.24 + yaml: 2.3.1 + dev: true + + /postcss-modules-extract-imports@3.0.0(postcss@8.4.24): + resolution: {integrity: sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.24 + dev: true + + /postcss-modules-local-by-default@4.0.3(postcss@8.4.24): + resolution: {integrity: sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + icss-utils: 5.1.0(postcss@8.4.24) + postcss: 8.4.24 + postcss-selector-parser: 6.0.13 + postcss-value-parser: 4.2.0 + dev: true + + /postcss-modules-scope@3.0.0(postcss@8.4.24): + resolution: {integrity: sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + postcss: 8.4.24 + postcss-selector-parser: 6.0.13 + dev: true + + /postcss-modules-values@4.0.0(postcss@8.4.24): + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + dependencies: + icss-utils: 5.1.0(postcss@8.4.24) + postcss: 8.4.24 + dev: true + + /postcss-modules@6.0.0(postcss@8.4.24): + resolution: {integrity: sha512-7DGfnlyi/ju82BRzTIjWS5C4Tafmzl3R79YP/PASiocj+aa6yYphHhhKUOEoXQToId5rgyFgJ88+ccOUydjBXQ==} + peerDependencies: + postcss: ^8.0.0 + dependencies: + generic-names: 4.0.0 + icss-utils: 5.1.0(postcss@8.4.24) + lodash.camelcase: 4.3.0 + postcss: 8.4.24 + postcss-modules-extract-imports: 3.0.0(postcss@8.4.24) + postcss-modules-local-by-default: 4.0.3(postcss@8.4.24) + postcss-modules-scope: 3.0.0(postcss@8.4.24) + postcss-modules-values: 4.0.0(postcss@8.4.24) + string-hash: 1.1.3 + dev: true + + /postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + dev: true + + /postcss@8.4.24: + resolution: {integrity: sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + dev: true + + /preact@10.15.1: + resolution: {integrity: sha512-qs2ansoQEwzNiV5eAcRT1p1EC/dmEzaATVDJNiB3g2sRDWdA7b7MurXdJjB2+/WQktGWZwxvDrnuRFbWuIr64g==} + dev: true + + /prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + + /pretty-ms@7.0.1: + resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==} + engines: {node: '>=10'} + dependencies: + parse-ms: 2.1.0 + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + dev: true + + /property-information@6.2.0: + resolution: {integrity: sha512-kma4U7AFCTwpqq5twzC1YVIDXSqg6qQK6JN0smOw8fgRy1OkMi0CYSzFmsy6dnqSenamAtj0CyXMUJ1Mf6oROg==} + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /proxy-agent@5.0.0: + resolution: {integrity: sha512-gkH7BkvLVkSfX9Dk27W6TyNOWWZWRilRfk1XxGNWOYJ2TuedAv1yFpCaU9QSBmBe716XOTNpYNOzhysyw8xn7g==} + engines: {node: '>= 8'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + lru-cache: 5.1.1 + pac-proxy-agent: 5.0.0 + proxy-from-env: 1.1.0 + socks-proxy-agent: 5.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true + + /pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /react-refresh@0.14.0: + resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==} + engines: {node: '>=0.10.0'} + dev: true + + /readable-stream@1.1.14: + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /recast@0.21.5: + resolution: {integrity: sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.15.2 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.6.0 + dev: true + + /regenerate-unicode-properties@10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + dev: true + + /regenerator-transform@0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.22.5 + dev: true + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /remark-frontmatter@4.0.1: + resolution: {integrity: sha512-38fJrB0KnmD3E33a5jZC/5+gGAC2WKNiPw1/fdXJvijBlhA7RCsvJklrYJakS0HedninvaCYW8lQGf9C918GfA==} + dependencies: + '@types/mdast': 3.0.11 + mdast-util-frontmatter: 1.0.1 + micromark-extension-frontmatter: 1.1.1 + unified: 10.1.2 + dev: true + + /remark-mdx-frontmatter@1.1.1: + resolution: {integrity: sha512-7teX9DW4tI2WZkXS4DBxneYSY7NHiXl4AKdWDO9LXVweULlCT8OPWsOjLEnMIXViN1j+QcY8mfbq3k0EK6x3uA==} + engines: {node: '>=12.2.0'} + dependencies: + estree-util-is-identifier-name: 1.1.0 + estree-util-value-to-estree: 1.3.0 + js-yaml: 4.1.0 + toml: 3.0.0 + dev: true + + /remark-parse@10.0.2: + resolution: {integrity: sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==} + dependencies: + '@types/mdast': 3.0.11 + mdast-util-from-markdown: 1.3.1 + unified: 10.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /remark-rehype@9.1.0: + resolution: {integrity: sha512-oLa6YmgAYg19zb0ZrBACh40hpBLteYROaPLhBXzLgjqyHQrN+gVP9N/FJvfzuNNuzCutktkroXEZBrxAxKhh7Q==} + dependencies: + '@types/hast': 2.3.4 + '@types/mdast': 3.0.11 + mdast-util-to-hast: 11.3.0 + unified: 10.1.2 + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /require-like@0.1.2: + resolution: {integrity: sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==} + dev: true + + /resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve.exports@2.0.2: + resolution: {integrity: sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==} + engines: {node: '>=10'} + dev: true + + /resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + dependencies: + is-core-module: 2.12.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + dependencies: + lowercase-keys: 2.0.0 + dev: true + + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup@3.26.0: + resolution: {integrity: sha512-YzJH0eunH2hr3knvF3i6IkLO/jTjAEwU4HoMUbQl4//Tnl3ou0e7P5SjxdDr8HQJdeUJShlbEHXrrnEHy1l7Yg==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.6.0 + dev: true + + /sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + dependencies: + mri: 1.2.0 + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /search-insights@2.6.0: + resolution: {integrity: sha512-vU2/fJ+h/Mkm/DJOe+EaM5cafJv/1rRTZpGJTuFPf/Q5LjzgMDsqPdSaZsAe+GAWHHsfsu+rQSAn6c8IGtBEVw==} + engines: {node: '>=8.16.0'} + dev: true + + /semver@6.1.1: + resolution: {integrity: sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==} + hasBin: true + dev: true + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver@7.3.8: + resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /semver@7.5.3: + resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + 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 + transitivePeerDependencies: + - supports-color + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /set-cookie-parser@2.6.0: + resolution: {integrity: sha512-RVnVQxTXuerk653XfuliOxBP81Sf0+qfQE73LIYKcyMYHG94AuH0kgrQpRDuTZnSmjpysHmzxJXKNfa6PjFhyQ==} + dev: true + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shiki@0.14.3: + resolution: {integrity: sha512-U3S/a+b0KS+UkTyMjoNojvTgrBHjgp7L6ovhFVZsXmBGnVdQ4K4U9oK0z63w538S91ATngv1vXigHCSWOwnr+g==} + dependencies: + ansi-sequence-parser: 1.1.0 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /signal-exit@4.0.2: + resolution: {integrity: sha512-MY2/qGx4enyjprQnFaZsHib3Yadh3IXyV2C321GY0pjGfVBu4un0uDJkwgdxqO+Rdx8JMT8IfJIRwbYVz3Ob3Q==} + engines: {node: '>=14'} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + dev: true + + /socks-proxy-agent@5.0.1: + resolution: {integrity: sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + socks: 2.7.1 + transitivePeerDependencies: + - supports-color + dev: true + + /socks@2.7.1: + resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} + engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} + dependencies: + ip: 2.0.0 + smart-buffer: 4.2.0 + dev: true + + /sort-object-keys@1.1.3: + resolution: {integrity: sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==} + dev: true + + /sort-package-json@1.57.0: + resolution: {integrity: sha512-FYsjYn2dHTRb41wqnv+uEqCUvBpK3jZcTp9rbz2qDTmel7Pmdtf+i2rLaaPMRZeSVM60V3Se31GyWFpmKs4Q5Q==} + hasBin: true + dependencies: + detect-indent: 6.1.0 + detect-newline: 3.1.0 + git-hooks-list: 1.0.3 + globby: 10.0.0 + is-plain-obj: 2.1.0 + sort-object-keys: 1.1.3 + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + + /source-map@0.7.4: + resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==} + engines: {node: '>= 8'} + dev: true + + /space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + dev: true + + /ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: true + + /string-hash@1.1.3: + resolution: {integrity: sha512-kJUvRUFK49aub+a7T1nNE66EJbZBMnBgoC1UbCZ5n6bsZKBRga4KgBRTMn/pFkeCZSYtNeSyMxPDM0AXWELk2A==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string_decoder@0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /stringify-entities@4.0.3: + resolution: {integrity: sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g==} + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /style-to-object@0.4.1: + resolution: {integrity: sha512-HFpbb5gr2ypci7Qw+IOhnP2zOU7e77b+rzM+wTzXzfi1PrtBCX0E7Pk4wL4iTLnhzZ+JgEGAhX81ebTg/aYjQw==} + dependencies: + inline-style-parser: 0.1.1 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /tabbable@6.2.0: + resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} + dev: true + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /tar@6.1.15: + resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + + /time-span@4.0.0: + resolution: {integrity: sha512-MyqZCTGLDZ77u4k+jqg4UlrzPTPZ49NDlaekU6uuFaJLzPIN1woaRXCbGeqOfxwc3Y37ZROGAJ614Rdv7Olt+g==} + engines: {node: '>=10'} + dependencies: + convert-hrtime: 3.0.0 + dev: true + + /tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + dependencies: + os-tmpdir: 1.0.2 + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + dev: true + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /toml@3.0.0: + resolution: {integrity: sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w==} + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /trough@2.1.0: + resolution: {integrity: sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g==} + dev: true + + /ts-morph@12.0.0: + resolution: {integrity: sha512-VHC8XgU2fFW7yO1f/b3mxKDje1vmyzFXHWzOYmKEkCEwcLjDtbdLgBQviqj4ZwP4MJkQtRo6Ha2I29lq/B+VxA==} + dependencies: + '@ts-morph/common': 0.11.1 + code-block-writer: 10.1.1 + dev: true + + /ts-node@10.9.1(@types/node@14.18.33)(typescript@4.9.5): + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + 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 + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.9 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 14.18.33 + acorn: 8.9.0 + acorn-walk: 8.2.0 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 4.9.5 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + dev: true + + /ts-toolbelt@6.15.5: + resolution: {integrity: sha512-FZIXf1ksVyLcfr7M317jbB67XFJhOO1YqdTcuGaq9q5jLUoTikukZ+98TPjKiP2jC5CgmYdWWYs0s2nLSU0/1A==} + dev: true + + /tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@2.6.0: + resolution: {integrity: sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA==} + dev: true + + /type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: true + + /type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /ufo@1.1.2: + resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} + dev: true + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unified@10.1.2: + resolution: {integrity: sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==} + dependencies: + '@types/unist': 2.0.6 + bail: 2.0.2 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 4.1.0 + trough: 2.1.0 + vfile: 5.3.7 + dev: true + + /unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + dependencies: + unique-slug: 2.0.2 + dev: true + + /unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + dependencies: + imurmurhash: 0.1.4 + dev: true + + /unist-builder@3.0.1: + resolution: {integrity: sha512-gnpOw7DIpCA0vpr6NqdPvTWnlPTApCTRzr+38E6hCWx3rz/cjo83SsKIlS1Z+L5ttScQ2AwutNnb8+tAvpb6qQ==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-generated@2.0.1: + resolution: {integrity: sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==} + dev: true + + /unist-util-is@5.2.1: + resolution: {integrity: sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-position-from-estree@1.1.2: + resolution: {integrity: sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-position@4.0.4: + resolution: {integrity: sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-remove-position@4.0.2: + resolution: {integrity: sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==} + dependencies: + '@types/unist': 2.0.6 + unist-util-visit: 4.1.2 + dev: true + + /unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-visit-parents@5.1.3: + resolution: {integrity: sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 5.2.1 + dev: true + + /unist-util-visit@4.1.2: + resolution: {integrity: sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 5.2.1 + unist-util-visit-parents: 5.1.3 + dev: true + + /universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.9): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.9 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + dequal: 2.0.3 + diff: 5.1.0 + kleur: 4.1.5 + sade: 1.8.1 + dev: true + + /v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + dev: true + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /vercel@31.0.1(@types/node@14.18.33): + resolution: {integrity: sha512-Tf6PsIseRtAw/PETRfBdGqnbG/el1g0prwaKCXm6Dq5CcKRoya3ntT2E38fHE9pXIPDqE1XdTn9F1crKm8sKAQ==} + engines: {node: '>= 14'} + hasBin: true + requiresBuild: true + dependencies: + '@vercel/build-utils': 6.8.0 + '@vercel/go': 2.5.1 + '@vercel/hydrogen': 0.0.64 + '@vercel/next': 3.8.8 + '@vercel/node': 2.15.3 + '@vercel/python': 3.1.60 + '@vercel/redwood': 1.1.15 + '@vercel/remix-builder': 1.8.15(@types/node@14.18.33) + '@vercel/ruby': 1.3.76 + '@vercel/static-build': 1.3.38 + transitivePeerDependencies: + - '@remix-run/serve' + - '@swc/core' + - '@swc/wasm' + - '@types/node' + - bluebird + - bufferutil + - encoding + - less + - sass + - stylus + - sugarss + - supports-color + - terser + - ts-node + - utf-8-validate + dev: true + + /vfile-message@3.1.4: + resolution: {integrity: sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==} + dependencies: + '@types/unist': 2.0.6 + unist-util-stringify-position: 3.0.3 + dev: true + + /vfile@5.3.7: + resolution: {integrity: sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==} + dependencies: + '@types/unist': 2.0.6 + is-buffer: 2.0.5 + unist-util-stringify-position: 3.0.3 + vfile-message: 3.1.4 + dev: true + + /vite-node@0.28.5(@types/node@14.18.33): + resolution: {integrity: sha512-LmXb9saMGlrMZbXTvOveJKwMTBTNUH66c8rJnQ0ZPNX+myPEol64+szRzXtV5ORb0Hb/91yq+/D3oERoyAt6LA==} + engines: {node: '>=v14.16.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.4.0 + pathe: 1.1.1 + picocolors: 1.0.0 + source-map: 0.6.1 + source-map-support: 0.5.21 + vite: 4.3.9(@types/node@14.18.33) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite@4.3.9(@types/node@14.18.33): + resolution: {integrity: sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 14.18.33 + esbuild: 0.17.19 + postcss: 8.4.24 + rollup: 3.26.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitepress@1.0.0-beta.3(@algolia/client-search@4.18.0)(@types/node@14.18.33)(search-insights@2.6.0): + resolution: {integrity: sha512-GR5Pvr/o343NN1M4Na1shhDYZRrQbjmLq7WE0lla0H8iDPAsHE8agTHLWfu3FWx+3q2KA29sv16+0O9RQKGjlA==} + hasBin: true + dependencies: + '@docsearch/css': 3.5.1 + '@docsearch/js': 3.5.1(@algolia/client-search@4.18.0)(search-insights@2.6.0) + '@vitejs/plugin-vue': 4.2.3(vite@4.3.9)(vue@3.3.4) + '@vue/devtools-api': 6.5.0 + '@vueuse/core': 10.2.1(vue@3.3.4) + '@vueuse/integrations': 10.2.1(focus-trap@7.4.3)(vue@3.3.4) + body-scroll-lock: 4.0.0-beta.0 + focus-trap: 7.4.3 + mark.js: 8.11.1 + minisearch: 6.1.0 + shiki: 0.14.3 + vite: 4.3.9(@types/node@14.18.33) + vue: 3.3.4 + transitivePeerDependencies: + - '@algolia/client-search' + - '@types/node' + - '@types/react' + - '@vue/composition-api' + - async-validator + - axios + - change-case + - drauu + - fuse.js + - idb-keyval + - jwt-decode + - less + - nprogress + - qrcode + - react + - react-dom + - sass + - search-insights + - sortablejs + - stylus + - sugarss + - terser + - universal-cookie + dev: true + + /vm2@3.9.19: + resolution: {integrity: sha512-J637XF0DHDMV57R6JyVsTak7nIL8gy5KH4r1HiwWLf/4GBbb5MKL5y7LpmF4A8E2nR6XmzpmMFQ7V7ppPTmUQg==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + acorn: 8.9.0 + acorn-walk: 8.2.0 + dev: true + + /vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + dev: true + + /vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + dev: true + + /vue-demi@0.14.5(vue@3.3.4): + resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.4 + dev: true + + /vue@3.3.4: + resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/runtime-dom': 3.3.4 + '@vue/server-renderer': 3.3.4(vue@3.3.4) + '@vue/shared': 3.3.4 + dev: true + + /wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + dependencies: + defaults: 1.0.4 + dev: true + + /web-vitals@0.2.4: + resolution: {integrity: sha512-6BjspCO9VriYy12z356nL6JBS0GYeEcA457YyRzD+dD6XYCQ75NKhcOHUMHentOE7OcVCIXXDvOm0jKFfQG2Gg==} + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: true + + /word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + 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 + dev: true + + /xdm@2.1.0: + resolution: {integrity: sha512-3LxxbxKcRogYY7cQSMy1tUuU1zKNK9YPqMT7/S0r7Cz2QpyF8O9yFySGD7caOZt+LWUOQioOIX+6ZzCoBCpcAA==} + dependencies: + '@rollup/pluginutils': 4.2.1 + '@types/estree-jsx': 0.0.1 + astring: 1.8.6 + estree-util-build-jsx: 2.2.2 + estree-util-is-identifier-name: 2.1.0 + estree-walker: 3.0.3 + got: 11.8.6 + hast-util-to-estree: 2.3.3 + loader-utils: 2.0.4 + markdown-extensions: 1.1.1 + mdast-util-mdx: 1.1.0 + micromark-extension-mdxjs: 1.0.1 + periscopic: 3.1.0 + remark-parse: 10.0.2 + remark-rehype: 9.1.0 + source-map: 0.7.4 + unified: 10.1.2 + unist-util-position-from-estree: 1.1.2 + unist-util-stringify-position: 3.0.3 + unist-util-visit: 4.1.2 + vfile: 5.3.7 + optionalDependencies: + deasync: 0.1.28 + transitivePeerDependencies: + - supports-color + dev: true + + /xregexp@2.0.0: + resolution: {integrity: sha512-xl/50/Cf32VsGq/1R8jJE5ajH1yMCQkpmoS10QbFZWl2Oor4H0Me64Pu2yxvsRWK3m6soJbmGfzSR7BYmDcWAA==} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml@2.3.1: + resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + engines: {node: '>= 14'} + dev: true + + /yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + dev: true diff --git a/docs/public/dark-logo.svg b/docs/public/dark-logo.svg new file mode 100644 index 00000000..0bb7c9c0 --- /dev/null +++ b/docs/public/dark-logo.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/docs/public/light-logo.svg b/docs/public/light-logo.svg new file mode 100644 index 00000000..63272925 --- /dev/null +++ b/docs/public/light-logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/docs/public/social.png b/docs/public/social.png new file mode 100644 index 00000000..73081939 Binary files /dev/null and b/docs/public/social.png differ diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 00000000..1b32b4dc --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://github.com/vuejs/tsconfig + "extends": "@vue/tsconfig/tsconfig.json", +} diff --git a/docs/usage/webui.md b/docs/usage/webui.md new file mode 100644 index 00000000..dc76035c --- /dev/null +++ b/docs/usage/webui.md @@ -0,0 +1,44 @@ +# WebUI 使用说明 + +## 添加合集 + +AB 提供了两种手动下载的方式: +**Collect** 和 **Subscribe**。 +其中 **Collect** 为手动下载全部剧集,适用于下载已经完结的番剧。 +**Subscribe** 为手动添加自动下载规则以及对应的 RSS 链接,适用于下载尚未完结的番剧。 + +### 解析 RSS 链接 + +AB 支持解析所有资源站的合集 RSS 链接,在对应的资源站找到对应番剧合集 RSS,点击 AB 右上角的 **+** 号,在弹出的窗口中粘贴 RSS 链接即可。 + +### 添加下载 + +如果正常解析,则会弹出一个窗口,显示解析到的番剧信息,点击 **Collect** 或者 **Subscribe** 即可添加到下载队列。 + +### 常见问题 + +如果出现解析错误,可能是由于 RSS 链接不正确,或者 RSS 中字幕组的命名不支持解析。 + +## 管理番剧 + +3.0 版本之后 AB 在 WebUI 中提供了手动管理番剧的功能,可以手动调整解析不正确的番剧信息。 + +### 修改番剧信息 + +在番剧列表中,点击番剧海报,即可进入番剧信息页面。 +修改番剧信息后,点击 **Apply** 即可。 +此时 AB 会根据你修改的信息重新调整目录并自动重命名。 + + +### 删除番剧 + +在 3.0 之后 AB 可以手动删除番剧,点击番剧海报,进入番剧信息页面,点击 **Delete** 即可删除番剧。 + +⚠️删除番剧之后,如果 RSS 中没有取消订阅,AB 仍然会重新解析,如果想禁用下载规则请使用[禁用番剧](#禁用番剧) + +### 禁用番剧 + +在 3.0 之后 AB 可以手动禁用番剧,点击番剧海报,进入番剧信息页面,点击 **Disable** 即可禁用番剧。 + +禁用之后番剧海报会变灰,并且排列在最后。如果想要重新启用下载规则,请点击 **Enable**。 + diff --git a/docs/use/使用说明.md b/docs/use/使用说明.md new file mode 100644 index 00000000..992a46e7 --- /dev/null +++ b/docs/use/使用说明.md @@ -0,0 +1,171 @@ +# API + +## 与 AutoBangumi 数据相关的 API + +### `api/v1/log` + +查看日志 + +```bash +curl -X GET http://ab_host:7892/api/v1/log +``` + +### `api/v1/data` + +获得当前 AB 中的存储信息 + +```bash +curl --request GET -sL \ + --url 'http://ab_host:7892/api/v1/data'\ +``` + +### `api/v1/resetRule` + +重置 AB 的数据,程序会在下一轮检索中重新添加 RSS 订阅信息。 + +```bash +curl --request GET -sL \ + --url 'http://ab_host:7892/api/v1/resetRule'\ +``` + +### `api/v1/removeRule/{name}` + +删除规则 + +```bash +curl --request GET -sL \ + --url 'http://ab_host:7892/api/v1/removeRule/{name}'\ +``` + +## 订阅相关的 API + +如果番剧还在更新,请使用 subscribe 来订阅,如果番剧已经完结,请使用 collection 来下载。 + +### `api/v1/subscribe` + +添加全集订阅 + +```bash +curl --request POST -sL \ + --url 'http://host:7892/api/v1/subscribe'\ + --data '{"rss_link":"link"}'\ + --header 'Content-Type: application/json' +``` + +### `api/v1/collection/` + +```bash +curl --request POST -sL \ + --url 'http://host:7892/api/v1/collection/'\ + --data '{"rss_link":"link"}'\ + --header 'Content-Type: application/json' +``` + +# 环境变量说明 + +## 注意 + +环境变量相关配置在 `2.6` 以后的版本中已经移除,现在使用 `config.json` 来配置系统设置。 + +## 环境列表 + +| 环境变量 | 作用 | 参数 | +| ------------------------ | ---------------------------------------------------- | -------------------- | +| `TZ` | 时区 | `Asia/Shanghai` | +| `AB_INTERVAL_TIME` | 间隔时间 | `7200` | +| `AB_RENAME_FREQ` | 在一个运行周期内重命名频率 | `20` | +| `AB_DOWNLOADER_HOST` | qBittorrent 的地址和端口号 | `localhost:8080` | +| `AB_DOWNLOADER_USERNAME` | qBittorrent 的用户名 | `admin` | +| `AB_DOWNLOADER_PASSWORD` | qBittorrent 的密码 | `adminadmin` | +| `AB_METHOD` | 重命名方法 `normal` 保留字幕组信息, `pn` 为纯净模式 | `pn` | +| `AB_GROUP_TAG` | 是否在下载规则中添加组名 | `False` | +| `AB_DOWNLOAD_PATH` | qBittorrent 中的下载路径 | `/downloads/Bangumi` | +| `AB_RSS` | RSS 订阅地址 | 必填项 | +| `AB_ENABLE_TMDB` | 启动 TMDB 解析 | `False` | +| `AB_LANGUAGE` | 选择语言 | `zh` | +| `AB_NOT_CONTAIN` | 输入想要过滤的元素 | `720` | +| `AB_DEBUG_MODE` | 调试模式 | `False` | +| `AB_EP_COMPLETE` | 历史番剧下载 | `False` | +| `AB_REMOVE_BAD_BT` | 碰到无法重命名的合集等,自动删除种子 | `False` | +| `AB_WEBUI_PORT` | Web API | `7892 ` | +| `AB_HTTP_PROXY` | HTTP 代理 | `127.0.0.1:6352` | +| `AB_SOCKS` | SOCKS5 代理 | `HOST,PORT,USR,PWD` | +| `AB_RENAME` | RENAME 开关 | `True` | +| `AB_RSS_COLLECTOR` | RSS 解析器开关 | `True` | +| `AB_RESET_FOLDER` | 修复错误命名文件夹 | `False` | + +## 进阶参数说明 + +### 与 qBittorrent 连接 + +- `AB_DOWNLOADER_HOST`: qBittorrent 的地址和端口号,如果开启 HTTPS 请使用 `https://` 开头。 + +### 运行相关 + +`AB_INTERVAL_TIME`: 解析器的运行间隔时间,单位为秒,默认为 7200 秒,即两个小时检查一次 RSS 更新。 + +`AB_RENAME_FREQ`: 在一个运行周期内重命名频率,默认为 20,即 6 分钟运行一次。 + +### 文件路径以及重命名相关 + +`AB_METHOD`: 重命名方法 + +- `normal` 保留字幕组 +- `pn` 为纯净模式,不保留字幕组,不保留其他信息,只保留名称,会根据 `Season` 文件夹的名称重命名。 +- `advance` 为高级模式,基于文件夹名称重命名,不保留其他信息。 + - 源文件路径:`/downloads/Bangumi/约会大作战/Season 4/DATE A LIVE - 1.mp4` >> `/downloads/Bangumi/约会大作战/Season 1/约会大作战 S04E01.mp4` +- `none` 为空模式,不重命名。 + +`AB_ENABLE_TMDB`: 启动 TMDB 解析, 建议同时启用代理。 + +`AB_LANGUAGE`: TMDB 解析后选择语言,仅在 `TMDB` 开启时有效。 + +- `zh` 中文 +- `jp` 日语 + +### 下载和过滤相关 + +`AB_GROUP_TAG`: 是否在下载规则中添加组名,方便查看。开启后规则命名为 [组名]规则名,关闭后规则命名为 [规则名] + +`AB_NOT_CONTAIN`: 输入想要过滤的元素,如 720,1080,等。 + +- 不同的元素用 `|` 分隔,例如 `720|CHT` +- 可以使用正则表达式,但是需要注意,特殊符号需要转义,例如 `\(` 表示 `(`。 +- 这个选项建议填写:`720|\d+-\d+`,如果过滤选项添加过多,会影响到正常的 RSS 识别。对于番剧单独的自定义可以在 qBitorrent 中自定义。 + +`AB_EP_COMPLETE`: 历史番剧下载,开启后,将会下载已加入时之前的剧集。 + +`AB_REMOVE_BAD_BT`: 碰到无法重命名的合集等,自动删除种子 + +`AB_RESET_FOLDER`: 修复错误命名文件夹,如 S01 >> Season 1 + +### 网络代理相关 + +`AB_WEBUI_PORT`: HTTP API Port + +`AB_HTTP_PROXY`: 开启 HTTP 代理,填入 HTTP 代理服务器地址和端口号 + +`AB_SOCKS`:开启 SOCKS5 代理 + +- `HOST,PORT,USR,PWD` + +### 调试模式 + +`AB_DEBUG_MODE`: 调试模式 + +### 功能开关 + +`AB_RENAME`: RENAME 开关 + +`AB_RSS_COLLECTOR`: RSS 解析器开关 + +# 如何正确的使用 AutoBangumi 以及 qBittorrent + +## 如何使用 AB 重命名其他番剧 + +- 只需要在 QB 中将种子类型设置为 Bangumi 即可被 AB 识别并重命名。 + +## 以下操作不影响程序正常运行 + +- 在 QB 中更改自动下载规则,更改自动下载路径 +- 在 QB 中按照规范更改文件路径 diff --git a/docs/use/配置选项说明.md b/docs/use/配置选项说明.md new file mode 100644 index 00000000..4ea56461 --- /dev/null +++ b/docs/use/配置选项说明.md @@ -0,0 +1,147 @@ +# 配置选项说明 + +从 `2.6` 版本之后,AutoBangumi 使用 `config.json` 来配置系统设置。 +初次运行 AutoBangumi 时会自动生成 `config.json` 文件,如果需要修改配置,可以直接修改 `config.json` 文件,也可以在 Web 界面中修改。 + +## 升级 + +如果你是从 `2.5` 版本升级到 `2.6` 版本,AB 会自动迁移你的配置文件,在首次升级完成之后,修改环境变量将对 AB 运行不生效。 +后续配置修改请直接修改 `config.json` 文件,或者在 Web 界面中修改。 + +## 配置文件参数说明: + +### 程序运行参数 + +配置文件部分:`program` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|-------------|------------|----------|------------|------| +| |rss_time | RSS 检查时间间隔 | 以秒为单位的整数 | RSS 检查时间间隔 | 7200 | +| rename_time | 重命名检查时间间隔 | 以秒为单位的整数 | 重命名检查时间间隔 | 60 | +| webui_port | WebUI 端口 | 以整数为单位 | WebUI 端口 | 7892 | + +- `rss_time` 和 `rename_time` 两个参数的单位为秒,如果你需要设置为分钟,请自行转换为秒。 +- `rss_time` 为 RSS 检查时间间隔,如果你需要修改 RSS 检查时间间隔,请修改此参数。 +- `rename_time` 为重命名检查时间间隔,如果你需要修改重命名检查时间间隔,请修改此参数。 +- `webui_port` 为 WebUI 端口,如果你需要修改 WebUI 端口,请修改此参数。 + +### 下载器参数 + +配置文件部分:`downloader` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|----------|-------------|------|-------------|--------------------| +| type | 下载器类型 | 字符串 | 下载器类型 | qbittorrent | +| host | 下载器地址 | 字符串 | 下载器地址 | 172.17.0.1:8080 | +| username | 下载器用户名 | 字符串 | 下载器用户名 | admin | +| password | 下载器密码 | 字符串 | 下载器密码 | adminadmin | +| path | 下载器下载路径 | 字符串 | 下载器下载路径 | /downloads/Bangumi | +| ssl | 下载器是否使用 SSL | 布尔值 | 下载器是否使用 SSL | false | + +- `type` 为下载器类型,目前支持 `qbittorrent` 下载器,目前暂不支持修改。 +- `host` 为下载器地址。[下载器链接问题][1] +- `path` 为映射的下载器下载路径。[下载器路径问题][2] +- `ssl` 为下载器是否使用 SSL。 + +### RSS 解析器参数 + +配置文件部分:`rss_parser` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|-------------|----------------|------|----------------|---------------| +| enable | RSS 解析器是否启用 | 布尔值 | RSS 解析器是否启用 | true | +| type | RSS 解析器类型 | 字符串 | RSS 解析器类型 | mikan | +| token | RSS 解析器 Token | 字符串 | RSS 解析器 Token | token | +| custom_url | RSS 解析器自定义 URL | 字符串 | RSS 解析器自定义 URL | mikanime.tv | +| parser_type | RSS 解析器解析类型 | 字符串 | RSS 解析器解析类型 | parser | +| filter | RSS 解析器过滤器 | 数组 | 过滤器 | [720,\d+-\d+] | +| language | RSS 解析器语言 | 字符串 | RSS 解析器语言 | zh | + + +- `type` 为 RSS 解析器类型,目前支持 `mikan` 。 +- `token` 为蜜柑计划的 Token。[蜜柑计划 Token 获取][3] +- `custom_url` 为自定义蜜柑计划地址。[自定义反代地址][4] +- `parser_type` 为 **官方标题** 解析器解析类型,支持类型如下: + - `parser` 为正则表达式解析器,使用正则表达式解析标题。 + - `mikan` 为蜜柑计划解析器,使用蜜柑计划解析标题。 + - `tmdb` 为 TMDB 解析器,使用 TMDB 解析标题。 +- `filter` 为 RSS 解析器过滤器,过滤器为数组,数组中的每一项为一个过滤器,过滤器为正则表达式,如果标题匹配正则表达式,则不会下载。 +- `language` 为 RSS 解析器语言,目前支持 `zh` 、 `jp` 、 `en` 三种语言。 + +### 番剧管理参数 + +配置文件部分:`bangumi_manager` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|--------------------|-----------------|------|------------|-------| +| enable | 番剧管理是否启用 | 布尔值 | 番剧管理是否启用 | true | +| eps_complete | 是否补全当季番剧 | 布尔值 | 番剧补全 | false | +| rename_method | 重命名方式 | 字符串 | 重命名方式 | pn | +| group_tag | 是否在下载规则中添加番剧组标签 | 布尔值 | 番剧组标签 | false | +| remove_bad_torrent | 是否删除错误的种子 | 布尔值 | 种子删除 | false | + + +- `eps_complete` 为是否补全当季番剧,如果开启,则会补全当季番剧,如果关闭,则不会补全当季番剧。 +- `rename_method` 为重命名方式,目前支持: + - `pn` 为 `Torrent Title S0XE0X.mp4` 的方式。 + - `advance` 为 `Official Title S0XE0X.mp4` 的方式。 + - `none` 为不重命名。 +- `group_tag` 为是否在下载规则中添加番剧组标签,如果开启,则会在下载规则中添加番剧组标签。 +- `remove_bad_torrent` 为是否删除错误的种子,如果开启,则会删除错误的种子。 + +### 日志参数 + +配置文件部分:`log` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|--------------|----------|------|------------|-------| +| debug_enable | 是否启用调试模式 | 布尔值 | 调试模式 | false | + + +### 代理参数 + +配置文件部分:`proxy` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|----------|--------|------|------------|-------| +| enable | 是否启用代理 | 布尔值 | 代理 | false | +| type | 代理类型 | 字符串 | 代理类型 | http | +| host | 代理地址 | 字符串 | 代理地址 | +| port | 代理端口 | 整数 | 代理端口 | +| username | 代理用户名 | 字符串 | 代理用户名 | +| password | 代理密码 | 字符串 | 代理密码 | + + +- `type` 为代理类型,目前支持 `http` 、 `socks5` 两种类型。 +- `username` 与 `password` 仅支持 `socks5` 代理。 + + +### 通知参数 + +配置文件部分:`notification` + +| 参数名 | 参数说明 | 参数类型 | WebUI 对应选项 | 默认值 | +|---------|------------|------|------------|----------| +| enable | 是否启用通知 | 布尔值 | 通知 | false | +| type | 通知类型 | 字符串 | 通知类型 | telegram | +| token | 通知 Token | 字符串 | 通知 Token | +| chat_id | 通知 Chat ID | 字符串 | 通知 Chat ID | + + +- `type` 为通知类型,目前支持 `telegram` 、 `serverchan` 、 `bark`、 `wecom` 四种类型。 +- `token` 为通知 Token,目前支持 `telegram` 、 `serverchan` 、 `bark`、 `wecom` 四种类型。 +- `chat_id` 为通知 Chat ID,仅在使用 `telegram` 通知时需要填写。[Telegram Bot 获取 Chat ID][5] +- 使用`wecom`时,chat_id参数框填写自建推送的url地址,同时需要在服务端增加[图文消息][6]类型。[Wecom酱配置说明][7] + + + +[1]: https://github.com/EstrellaXD/Auto_Bangumi/wiki +[2]: https://github.com/EstrellaXD/Auto_Bangumi/wiki +[3]: https://github.com/EstrellaXD/Auto_Bangumi/wiki/部署说明/#开始前准备 +[4]: https://github.com/EstrellaXD/Auto_Bangumi/wiki +[5]: https://github.com/EstrellaXD/Auto_Bangumi/wiki +[6]: https://github.com/umbors/wecomchan-alifun +[7]: https://github.com/easychen/wecomchan + + + diff --git a/docs/wiki b/docs/wiki deleted file mode 160000 index 519e381e..00000000 --- a/docs/wiki +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 519e381e8a1add62e76a39181ee61bad02816035 diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 00000000..080c6b21 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,15 @@ +#!/bin/bash +# shellcheck shell=bash + +umask ${UMASK} + +if [ -f /config/bangumi.json ]; then + mv /config/bangumi.json /app/data/bangumi.json +fi + +groupmod -o -g "${PGID}" ab +usermod -o -u "${PUID}" ab + +chown ab:ab -R /app /home/ab + +exec su-exec "${PUID}:${PGID}" python3 main.py \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 2c84d529..00000000 --- a/requirements.txt +++ /dev/null @@ -1,25 +0,0 @@ -anyio -bs4 -certifi -charset-normalizer -click -fastapi -h11 -idna -pydantic == 1.10 -PySocks -qbittorrent-api -requests -six -sniffio -soupsieve -typing_extensions -urllib3 -uvicorn -attrdict -jinja2 -python-dotenv -python-jose -passlib -bcrypt -python-multipart diff --git a/webui/.eslintignore b/webui/.eslintignore new file mode 100644 index 00000000..2247d5f9 --- /dev/null +++ b/webui/.eslintignore @@ -0,0 +1,2 @@ +/build +/dist diff --git a/webui/.eslintrc.json b/webui/.eslintrc.json new file mode 100644 index 00000000..b38260c0 --- /dev/null +++ b/webui/.eslintrc.json @@ -0,0 +1,8 @@ +{ + "extends": ["@antfu", "prettier", "plugin:storybook/recommended"], + "rules": { + "antfu/if-newline": ["off"], + "no-console": ["off"], + "vue/custom-event-name-casing": ["off"] + } +} diff --git a/webui/.husky/pre-commit b/webui/.husky/pre-commit new file mode 100644 index 00000000..9c2a7dd9 --- /dev/null +++ b/webui/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +cd ./webui && pnpm run lint:fix && pnpm run format diff --git a/webui/.neoconf.json b/webui/.neoconf.json new file mode 100644 index 00000000..b019fc2a --- /dev/null +++ b/webui/.neoconf.json @@ -0,0 +1,3 @@ +{ + "volar": { "enable": true } +} diff --git a/webui/.npmrc b/webui/.npmrc new file mode 100644 index 00000000..dbed7938 --- /dev/null +++ b/webui/.npmrc @@ -0,0 +1,3 @@ +public-hoist-pattern[]=@vue/runtime-core +public-hoist-pattern[]=*eslint* +public-hoist-pattern[]=*prettier* diff --git a/webui/.prettierignore b/webui/.prettierignore new file mode 100644 index 00000000..4875f84a --- /dev/null +++ b/webui/.prettierignore @@ -0,0 +1,6 @@ +/build +/dist +/pnpm-lock.yaml +auto-imports.d.ts +components.d.ts +router-type.d.ts diff --git a/webui/.prettierrc.json b/webui/.prettierrc.json new file mode 100644 index 00000000..544138be --- /dev/null +++ b/webui/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "singleQuote": true +} diff --git a/webui/.storybook/main.ts b/webui/.storybook/main.ts new file mode 100644 index 00000000..923d5af6 --- /dev/null +++ b/webui/.storybook/main.ts @@ -0,0 +1,24 @@ +import type { StorybookConfig } from '@storybook/vue3-vite'; +import Unocss from 'unocss/vite'; + +const config: StorybookConfig = { + stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'], + addons: [ + '@storybook/addon-links', + '@storybook/addon-essentials', + '@storybook/addon-interactions', + ], + framework: { + name: '@storybook/vue3-vite', + options: {}, + }, + docs: { + autodocs: 'tag', + }, + viteFinal(config) { + config.plugins?.push(Unocss()); + // Add other configuration here depending on your use case + return config; + }, +}; +export default config; diff --git a/webui/.storybook/preview.ts b/webui/.storybook/preview.ts new file mode 100644 index 00000000..74a1b88e --- /dev/null +++ b/webui/.storybook/preview.ts @@ -0,0 +1,17 @@ +import type { Preview } from '@storybook/vue3'; +import '@unocss/reset/tailwind-compat.css'; +import 'uno.css'; + +const preview: Preview = { + parameters: { + actions: { argTypesRegex: '^on[A-Z].*' }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + }, +}; + +export default preview; diff --git a/webui/.vscode/extensions.json b/webui/.vscode/extensions.json new file mode 100644 index 00000000..a7cea0b0 --- /dev/null +++ b/webui/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["Vue.volar"] +} diff --git a/webui/.vscode/settings.json b/webui/.vscode/settings.json new file mode 100644 index 00000000..1fb0955e --- /dev/null +++ b/webui/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "i18n-ally.localesPaths": ["src/i18n"], + "commentTranslate.targetLanguage": "zh-CN", + "i18n-ally.sourceLanguage": "en", + "typescript.tsdk": "node_modules/typescript/lib" +} diff --git a/webui/LICENSE b/webui/LICENSE new file mode 100644 index 00000000..a467ce28 --- /dev/null +++ b/webui/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Rewrite0 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/webui/README.md b/webui/README.md new file mode 100644 index 00000000..fa61d455 --- /dev/null +++ b/webui/README.md @@ -0,0 +1,3 @@ +# Auto_Bangumi_WebUI + +使用 Vue3 + TypeScript 构建的 [Auto_Bangumi](https://github.com/EstrellaXD/Auto_Bangumi) 的 WebUI diff --git a/webui/index.html b/webui/index.html new file mode 100644 index 00000000..356c7f49 --- /dev/null +++ b/webui/index.html @@ -0,0 +1,17 @@ + + + + + + + + + + + AutoBangumi + + +
+ + + diff --git a/webui/package.json b/webui/package.json new file mode 100644 index 00000000..f423c373 --- /dev/null +++ b/webui/package.json @@ -0,0 +1,71 @@ +{ + "name": "ab-webui", + "type": "module", + "version": "0.0.0", + "private": true, + "scripts": { + "prepare": "cd .. && husky install ./webui/.husky", + "build": "vue-tsc --noEmit && vite build", + "dev": "vite", + "format": "prettier --write .", + "format:check": "prettier --check .", + "lint": "eslint .", + "lint:fix": "eslint . --fix", + "preview": "vite preview", + "test": "vitest", + "storybook": "storybook dev -p 6006", + "build-storybook": "storybook build", + "generate-pwa-assets": "pwa-assets-generator --preset minimal public/images/logo.svg" + }, + "dependencies": { + "@headlessui/vue": "^1.7.13", + "@vueuse/components": "^10.4.1", + "@vueuse/core": "^8.9.4", + "axios": "^0.27.2", + "lodash": "^4.17.21", + "naive-ui": "^2.34.4", + "pinia": "^2.1.3", + "rxjs": "^7.8.1", + "vue": "^3.3.4", + "vue-i18n": "^9.2.2", + "vue-inline-svg": "^3.1.2", + "vue-router": "^4.2.1" + }, + "devDependencies": { + "@antfu/eslint-config": "^0.38.6", + "@icon-park/vue-next": "^1.4.2", + "@intlify/unplugin-vue-i18n": "^0.11.0", + "@storybook/addon-essentials": "^7.0.12", + "@storybook/addon-interactions": "^7.0.12", + "@storybook/addon-links": "^7.0.12", + "@storybook/blocks": "^7.0.12", + "@storybook/testing-library": "0.0.14-next.2", + "@storybook/vue3": "^7.0.12", + "@storybook/vue3-vite": "^7.0.12", + "@types/lodash": "^4.14.194", + "@types/node": "^18.16.14", + "@unocss/preset-attributify": "^0.55.3", + "@unocss/preset-rem-to-px": "^0.51.13", + "@unocss/reset": "^0.51.13", + "@vitejs/plugin-vue": "^4.2.0", + "@vue/runtime-dom": "^3.3.4", + "eslint": "^8.41.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-storybook": "^0.6.12", + "husky": "^8.0.3", + "prettier": "^2.8.8", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "sass": "^1.62.1", + "storybook": "^7.0.12", + "typescript": "^4.9.5", + "unocss": "^0.51.13", + "unplugin-auto-import": "^0.10.3", + "unplugin-vue-components": "^0.24.1", + "unplugin-vue-router": "^0.6.4", + "vite": "^4.3.5", + "vite-plugin-pwa": "^0.16.4", + "vitest": "^0.30.1", + "vue-tsc": "^1.6.4" + } +} diff --git a/webui/pnpm-lock.yaml b/webui/pnpm-lock.yaml new file mode 100644 index 00000000..21ca7efd --- /dev/null +++ b/webui/pnpm-lock.yaml @@ -0,0 +1,10298 @@ +lockfileVersion: '6.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +dependencies: + '@headlessui/vue': + specifier: ^1.7.13 + version: 1.7.13(vue@3.3.4) + '@vueuse/components': + specifier: ^10.4.1 + version: 10.4.1(vue@3.3.4) + '@vueuse/core': + specifier: ^8.9.4 + version: 8.9.4(vue@3.3.4) + axios: + specifier: ^0.27.2 + version: 0.27.2 + lodash: + specifier: ^4.17.21 + version: 4.17.21 + naive-ui: + specifier: ^2.34.4 + version: 2.34.4(vue@3.3.4) + pinia: + specifier: ^2.1.3 + version: 2.1.3(typescript@4.9.5)(vue@3.3.4) + rxjs: + specifier: ^7.8.1 + version: 7.8.1 + vue: + specifier: ^3.3.4 + version: 3.3.4 + vue-i18n: + specifier: ^9.2.2 + version: 9.2.2(vue@3.3.4) + vue-inline-svg: + specifier: ^3.1.2 + version: 3.1.2(vue@3.3.4) + vue-router: + specifier: ^4.2.1 + version: 4.2.1(vue@3.3.4) + +devDependencies: + '@antfu/eslint-config': + specifier: ^0.38.6 + version: 0.38.6(eslint@8.41.0)(typescript@4.9.5) + '@icon-park/vue-next': + specifier: ^1.4.2 + version: 1.4.2(vue@3.3.4) + '@intlify/unplugin-vue-i18n': + specifier: ^0.11.0 + version: 0.11.0(rollup@2.79.1)(vue-i18n@9.2.2) + '@storybook/addon-essentials': + specifier: ^7.0.12 + version: 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-interactions': + specifier: ^7.0.12 + version: 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-links': + specifier: ^7.0.12 + version: 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/blocks': + specifier: ^7.0.12 + version: 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/testing-library': + specifier: 0.0.14-next.2 + version: 0.0.14-next.2 + '@storybook/vue3': + specifier: ^7.0.12 + version: 7.0.12(vue@3.3.4) + '@storybook/vue3-vite': + specifier: ^7.0.12 + version: 7.0.12(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.3.5)(vue@3.3.4) + '@types/lodash': + specifier: ^4.14.194 + version: 4.14.194 + '@types/node': + specifier: ^18.16.14 + version: 18.16.14 + '@unocss/preset-attributify': + specifier: ^0.55.3 + version: 0.55.3 + '@unocss/preset-rem-to-px': + specifier: ^0.51.13 + version: 0.51.13 + '@unocss/reset': + specifier: ^0.51.13 + version: 0.51.13 + '@vitejs/plugin-vue': + specifier: ^4.2.0 + version: 4.2.3(vite@4.3.5)(vue@3.3.4) + '@vue/runtime-dom': + specifier: ^3.3.4 + version: 3.3.4 + eslint: + specifier: ^8.41.0 + version: 8.41.0 + eslint-config-prettier: + specifier: ^8.8.0 + version: 8.8.0(eslint@8.41.0) + eslint-plugin-storybook: + specifier: ^0.6.12 + version: 0.6.12(eslint@8.41.0)(typescript@4.9.5) + husky: + specifier: ^8.0.3 + version: 8.0.3 + prettier: + specifier: ^2.8.8 + version: 2.8.8 + react: + specifier: ^18.2.0 + version: 18.2.0 + react-dom: + specifier: ^18.2.0 + version: 18.2.0(react@18.2.0) + sass: + specifier: ^1.62.1 + version: 1.62.1 + storybook: + specifier: ^7.0.12 + version: 7.0.12 + typescript: + specifier: ^4.9.5 + version: 4.9.5 + unocss: + specifier: ^0.51.13 + version: 0.51.13(postcss@8.4.23)(rollup@2.79.1)(vite@4.3.5) + unplugin-auto-import: + specifier: ^0.10.3 + version: 0.10.3(@vueuse/core@8.9.4)(esbuild@0.17.19)(rollup@2.79.1)(vite@4.3.5) + unplugin-vue-components: + specifier: ^0.24.1 + version: 0.24.1(rollup@2.79.1)(vue@3.3.4) + unplugin-vue-router: + specifier: ^0.6.4 + version: 0.6.4(rollup@2.79.1)(vue-router@4.2.1)(vue@3.3.4) + vite: + specifier: ^4.3.5 + version: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + vite-plugin-pwa: + specifier: ^0.16.4 + version: 0.16.4(vite@4.3.5)(workbox-build@7.0.0)(workbox-window@7.0.0) + vitest: + specifier: ^0.30.1 + version: 0.30.1(sass@1.62.1) + vue-tsc: + specifier: ^1.6.4 + version: 1.6.4(typescript@4.9.5) + +packages: + + /@ampproject/remapping@2.2.1: + resolution: {integrity: sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@antfu/eslint-config-basic@0.38.6(@typescript-eslint/eslint-plugin@5.59.6)(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-g5hxtS98MsQ6plCQ1rPx/K9+7ZZmUgdsWx84PJCwbaSuSklP1jZjuhMcjOPn/LW5t9QAPeb74T9+QsK3+IyNKQ==} + peerDependencies: + eslint: '>=7.4.0' + dependencies: + eslint: 8.41.0 + eslint-plugin-antfu: 0.38.6(eslint@8.41.0)(typescript@4.9.5) + eslint-plugin-eslint-comments: 3.2.0(eslint@8.41.0) + eslint-plugin-html: 7.1.0 + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.6)(eslint@8.41.0) + eslint-plugin-jsonc: 2.8.0(eslint@8.41.0) + eslint-plugin-markdown: 3.0.0(eslint@8.41.0) + eslint-plugin-n: 15.7.0(eslint@8.41.0) + eslint-plugin-no-only-tests: 3.1.0 + eslint-plugin-promise: 6.1.1(eslint@8.41.0) + eslint-plugin-unicorn: 46.0.1(eslint@8.41.0) + eslint-plugin-unused-imports: 2.0.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0) + eslint-plugin-yml: 1.7.0(eslint@8.41.0) + jsonc-eslint-parser: 2.3.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + - typescript + dev: true + + /@antfu/eslint-config-ts@0.38.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-a7PY1xpJwjZwIciu8gboLJ2yYxB1HMCKKshuKvH8vcGv+af5X9wk0eLN3Paa72yytSZZ2fqxfD0AwXTW0n+oiA==} + peerDependencies: + eslint: '>=7.4.0' + typescript: '>=3.9' + dependencies: + '@antfu/eslint-config-basic': 0.38.6(@typescript-eslint/eslint-plugin@5.59.6)(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + eslint-plugin-jest: 27.2.1(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + dev: true + + /@antfu/eslint-config-vue@0.38.6(@typescript-eslint/eslint-plugin@5.59.6)(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-mC+MA7/WFXGIPR4RbdvaSWXjYJvBiloDzPaOILgbfPxWqROi5KzgMAYbRfHkXz0TaG2P1+wFiuf41unc3rq3ew==} + peerDependencies: + eslint: '>=7.4.0' + dependencies: + '@antfu/eslint-config-basic': 0.38.6(@typescript-eslint/eslint-plugin@5.59.6)(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@antfu/eslint-config-ts': 0.38.6(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + eslint-plugin-vue: 9.13.0(eslint@8.41.0) + local-pkg: 0.4.3 + transitivePeerDependencies: + - '@typescript-eslint/eslint-plugin' + - '@typescript-eslint/parser' + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - typescript + dev: true + + /@antfu/eslint-config@0.38.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-QH9RwKLgumLjkVfKNIrxtISlp6VqfduXVIS2uNlOfrj1hSSObOMzj0olcsKR2pzgTMQ6d5Uu9nrxvKjs/oO6fg==} + peerDependencies: + eslint: '>=7.4.0' + dependencies: + '@antfu/eslint-config-vue': 0.38.6(@typescript-eslint/eslint-plugin@5.59.6)(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + eslint-plugin-eslint-comments: 3.2.0(eslint@8.41.0) + eslint-plugin-html: 7.1.0 + eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.59.6)(eslint@8.41.0) + eslint-plugin-jsonc: 2.8.0(eslint@8.41.0) + eslint-plugin-n: 15.7.0(eslint@8.41.0) + eslint-plugin-promise: 6.1.1(eslint@8.41.0) + eslint-plugin-unicorn: 46.0.1(eslint@8.41.0) + eslint-plugin-vue: 9.13.0(eslint@8.41.0) + eslint-plugin-yml: 1.7.0(eslint@8.41.0) + jsonc-eslint-parser: 2.3.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - jest + - supports-color + - typescript + dev: true + + /@antfu/install-pkg@0.1.1: + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + dev: true + + /@antfu/utils@0.5.2: + resolution: {integrity: sha512-CQkeV+oJxUazwjlHD0/3ZD08QWKuGQkhnrKo3e6ly5pd48VUpXbb77q0xMU4+vc2CkJnDS02Eq/M9ugyX20XZA==} + dev: true + + /@antfu/utils@0.7.2: + resolution: {integrity: sha512-vy9fM3pIxZmX07dL+VX1aZe7ynZ+YyB0jY+jE6r3hOK6GNY2t6W8rzpFC4tgpbXUYABkFQwgJq2XYXlxbXAI0g==} + dev: true + + /@apideck/better-ajv-errors@0.3.6(ajv@8.12.0): + resolution: {integrity: sha512-P+ZygBLZtkp0qqOAJJVX4oX/sFo5JR3eBWwwuqHHhK0GIgQOKWrAfiAaWX0aArHkRWHMuggFEgAZNxVPwPZYaA==} + engines: {node: '>=10'} + peerDependencies: + ajv: '>=8' + dependencies: + ajv: 8.12.0 + json-schema: 0.4.0 + jsonpointer: 5.0.1 + leven: 3.1.0 + dev: true + + /@aw-web-design/x-default-browser@1.4.88: + resolution: {integrity: sha512-AkEmF0wcwYC2QkhK703Y83fxWARttIWXDmQN8+cof8FmFZ5BRhnNXGymeb1S73bOCLfWjYELxtujL56idCN/XA==} + hasBin: true + dependencies: + default-browser-id: 3.0.0 + dev: true + + /@babel/code-frame@7.21.4: + resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.18.6 + dev: true + + /@babel/compat-data@7.21.9: + resolution: {integrity: sha512-FUGed8kfhyWvbYug/Un/VPJD41rDIgoVVcR+FuzhzOYyRz5uED+Gd3SLZml0Uw2l2aHFb7ZgdW5mGA3G2cCCnQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/core@7.21.8: + resolution: {integrity: sha512-YeM22Sondbo523Sz0+CirSPnbj9bG3P0CdHcBZdqUuaeOaYEFbOLoGU7lebvGP6P5J/WE9wOn7u7C4J9HvS1xQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.21.4 + '@babel/generator': 7.21.9 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-module-transforms': 7.21.5 + '@babel/helpers': 7.21.5 + '@babel/parser': 7.21.9 + '@babel/template': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + convert-source-map: 1.9.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/generator@7.21.9: + resolution: {integrity: sha512-F3fZga2uv09wFdEjEQIJxXALXfz0+JaOb7SabvVMmjHxeVTuGW8wgE8Vp1Hd7O+zMTYtcfEISGRzPkeiaPPsvg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + + /@babel/helper-annotate-as-pure@7.18.6: + resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-builder-binary-assignment-operator-visitor@7.21.5: + resolution: {integrity: sha512-uNrjKztPLkUk7bpCNC0jEKDJzzkvel/W+HguzbN8krA+LPfC1CEobJEvAvGka2A/M+ViOqXdcRL0GqPUJSjx9g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-compilation-targets@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-1RkbFGUKex4lvsB9yhIfWltJM5cZKUftB2eNajaDv3dCMEp49iBG0K14uH8NnX9IPux2+mK7JGEOB0jn48/J6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/compat-data': 7.21.9 + '@babel/core': 7.21.8 + '@babel/helper-validator-option': 7.21.0 + browserslist: 4.21.5 + lru-cache: 5.1.1 + semver: 6.3.0 + dev: true + + /@babel/helper-create-class-features-plugin@7.21.8(@babel/core@7.21.8): + resolution: {integrity: sha512-+THiN8MqiH2AczyuZrnrKL6cAxFRRQDKW9h1YkBvbgKmAm6mwiacig1qT73DHIWMGo40GRnsEfN3LA+E6NtmSw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-member-expression-to-functions': 7.21.5 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-replace-supers': 7.21.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/helper-split-export-declaration': 7.18.6 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-create-regexp-features-plugin@7.21.8(@babel/core@7.21.8): + resolution: {integrity: sha512-zGuSdedkFtsFHGbexAvNuipg1hbtitDLo2XE8/uf6Y9sOQV1xsYX/2pNbtedp/X0eU1pIt+kGvaqHCowkRbS5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + regexpu-core: 5.3.2 + semver: 6.3.0 + dev: true + + /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.21.8): + resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} + peerDependencies: + '@babel/core': ^7.4.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + debug: 4.3.4 + lodash.debounce: 4.0.8 + resolve: 1.22.2 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-environment-visitor@7.21.5: + resolution: {integrity: sha512-IYl4gZ3ETsWocUWgsFZLM5i1BYx9SoemminVEXadgLBa9TdeorzgLKm8wWLA6J1N/kT3Kch8XIk1laNzYoHKvQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-function-name@7.21.0: + resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.21.9 + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-hoist-variables@7.18.6: + resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-member-expression-to-functions@7.21.5: + resolution: {integrity: sha512-nIcGfgwpH2u4n9GG1HpStW5Ogx7x7ekiFHbjjFRKXbn5zUvqO9ZgotCO4x1aNbKn/x/xOUaXEhyNHCwtFCpxWg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-module-imports@7.21.4: + resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-module-transforms@7.21.5: + resolution: {integrity: sha512-bI2Z9zBGY2q5yMHoBvJ2a9iX3ZOAzJPm7Q8Yz6YeoUjU/Cvhmi2G4QyTNyPBqqXSgTjUxRg3L0xV45HvkNWWBw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-simple-access': 7.21.5 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-validator-identifier': 7.19.1 + '@babel/template': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-optimise-call-expression@7.18.6: + resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-plugin-utils@7.21.5: + resolution: {integrity: sha512-0WDaIlXKOX/3KfBK/dwP1oQGiPh6rjMkT7HIRv7i5RR2VUMwrx5ZL0dwBkKx7+SW1zwNdgjHd34IMk5ZjTeHVg==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-wrap-function': 7.20.5 + '@babel/types': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-replace-supers@7.21.5: + resolution: {integrity: sha512-/y7vBgsr9Idu4M6MprbOVUfH3vs7tsIfnVWv/Ml2xgwvyH6LTngdfbf5AdsKwkJy4zgy1X/kuNrEKvhhK28Yrg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-member-expression-to-functions': 7.21.5 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/template': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helper-simple-access@7.21.5: + resolution: {integrity: sha512-ENPDAMC1wAjR0uaCUwliBdiSl1KBJAVnMTzXqi64c2MG8MPR6ii4qf7bSXDqSFbr4W6W028/rf5ivoHop5/mkg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-skip-transparent-expression-wrappers@7.20.0: + resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-split-export-declaration@7.18.6: + resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@babel/helper-string-parser@7.21.5: + resolution: {integrity: sha512-5pTUx3hAJaZIdW99sJ6ZUUgWq/Y+Hja7TowEnLNMm1VivRgZQL3vpBY3qUACVsvw+yQU6+YgfBVmcbLaZtrA1w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-identifier@7.19.1: + resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} + engines: {node: '>=6.9.0'} + + /@babel/helper-validator-option@7.21.0: + resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} + engines: {node: '>=6.9.0'} + dev: true + + /@babel/helper-wrap-function@7.20.5: + resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-function-name': 7.21.0 + '@babel/template': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/helpers@7.21.5: + resolution: {integrity: sha512-BSY+JSlHxOmGsPTydUkPf1MdMQ3M81x5xGCOVgWM3G8XH77sJ292Y2oqcp0CbbgxhqBuI46iUz1tT7hqP7EfgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/highlight@7.18.6: + resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + + /@babel/parser@7.21.9: + resolution: {integrity: sha512-q5PNg/Bi1OpGgx5jYlvWZwAorZepEudDMCLtj967aeS7WMont7dUZI46M2XwcIQqvUlMxWfdLFu4S/qSxeUu5g==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.21.5 + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.9 + '@babel/core': 7.21.8 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.8) + dev: true + + /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} + engines: {node: '>=4'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.21.8): + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.21.8): + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.21.8): + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-flow@7.21.4(@babel/core@7.21.8): + resolution: {integrity: sha512-l9xd3N+XG4fZRxEP3vXdK6RW7vN1Uf5dxzRC/09wV86wqZ/YYQooBIGNsiRdfNR3/q2/5pPzV4B54J/9ctX5jw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.21.8): + resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.21.8): + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.21.8): + resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.21.8): + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.21.8): + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.21.8): + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.21.8): + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.21.8): + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.21.8): + resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-arrow-functions@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-wb1mhwGOCaXHDTcsRYMKF9e5bbMgqwxtqa2Y1ifH96dXJPwbuLX9qHy3clhrxVqgMz7nyNXs8VkxdH8UBcjKqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-classes@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-optimise-call-expression': 7.18.6 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.21.5 + '@babel/helper-split-export-declaration': 7.18.6 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-computed-properties@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-TR653Ki3pAwxBxUe8srfF3e4Pe3FTA46uaNHYyQwIoM4oWKSoOZiDNyHJ0oIoDIUPSRQbQG7jzgVBX3FPVne1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/template': 7.21.9 + dev: true + + /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.21.8): + resolution: {integrity: sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-builder-binary-assignment-operator-visitor': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-flow': 7.21.4(@babel/core@7.21.8) + dev: true + + /@babel/plugin-transform-for-of@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-nYWpjKW/7j/I/mZkGVgHJXh4bA1sfdFnJoOXwJuj4m3Q2EraO/8ZyrkCau9P5tbHQk01RMSt6KYLCsW7730SXQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-function-name': 7.21.0 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-literals@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.21.8): + resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-module-transforms': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-commonjs@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-OVryBEgKUbtqMoB7eG2rs6UFexJi6Zj6FDXx+esBLPTCxCNxAY9o+8Di7IsUGJ+AVhp5ncK0fxWUBd0/1gPhrQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-module-transforms': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-simple-access': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.21.8): + resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-module-transforms': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-validator-identifier': 7.19.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-module-transforms': 7.21.5 + '@babel/helper-plugin-utils': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.21.8): + resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-replace-supers': 7.21.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.21.8): + resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-react-jsx@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-ELdlq61FpoEkHO6gFRpfj0kUgSwQTGoaEU8eMRoS8Dv3v6e7BjEAj5WMtIBRdHUeAioMhKP5HyxNzNnP+heKbA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-module-imports': 7.21.4 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8) + '@babel/types': 7.21.5 + dev: true + + /@babel/plugin-transform-regenerator@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-ZoYBKDb6LyMi5yCsByQ5jmXsHAQDDYeexT1Szvlmui+lADvfSecr5Dxd/PkrTC3pAD182Fcju1VQkB4oCp9M+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + regenerator-transform: 0.15.1 + dev: true + + /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-spread@7.20.7(@babel/core@7.21.8): + resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 + dev: true + + /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.21.8): + resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.21.8): + resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/helper-create-class-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/plugin-transform-unicode-escapes@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-LYm/gTOwZqsYohlvFUe/8Tujz75LqqVC2w+2qPHLR+WyWHGCZPN1KBpJCJn+4Bk4gOkQy/IXKIge6az5MqwlOg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.21.8): + resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-create-regexp-features-plugin': 7.21.8(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + dev: true + + /@babel/preset-env@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-wH00QnTTldTbf/IefEVyChtRdw5RJvODT/Vb4Vcxq1AZvtXj6T0YeX0cAcXhI6/BdGuiP3GcNIL4OQbI2DVNxg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.9 + '@babel/core': 7.21.8 + '@babel/helper-compilation-targets': 7.21.5(@babel/core@7.21.8) + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.21.8) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.21.8) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.21.8) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.21.8) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.21.8) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.21.8) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.21.8) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.21.8) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.21.8) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.21.8) + '@babel/plugin-transform-arrow-functions': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-async-to-generator': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-transform-classes': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-transform-computed-properties': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-destructuring': 7.21.3(@babel/core@7.21.8) + '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-duplicate-keys': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-transform-exponentiation-operator': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-for-of': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.21.8) + '@babel/plugin-transform-modules-commonjs': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-modules-systemjs': 7.20.11(@babel/core@7.21.8) + '@babel/plugin-transform-modules-umd': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5(@babel/core@7.21.8) + '@babel/plugin-transform-new-target': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.21.8) + '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-regenerator': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-reserved-words': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.21.8) + '@babel/plugin-transform-sticky-regex': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-transform-typeof-symbol': 7.18.9(@babel/core@7.21.8) + '@babel/plugin-transform-unicode-escapes': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.21.8) + '@babel/preset-modules': 0.1.5(@babel/core@7.21.8) + '@babel/types': 7.21.5 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.21.8) + babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.21.8) + babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.21.8) + core-js-compat: 3.30.2 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/preset-flow@7.21.4(@babel/core@7.21.8): + resolution: {integrity: sha512-F24cSq4DIBmhq4OzK3dE63NHagb27OPE3eWR+HLekt4Z3Y5MzIIUGF3LlLgV0gN8vzbDViSY7HnrReNVCJXTeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.21.8) + dev: true + + /@babel/preset-modules@0.1.5(@babel/core@7.21.8): + resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.21.8) + '@babel/types': 7.21.5 + esutils: 2.0.3 + dev: true + + /@babel/preset-typescript@7.21.5(@babel/core@7.21.8): + resolution: {integrity: sha512-iqe3sETat5EOrORXiQ6rWfoOg2y68Cs75B9wNxdPW4kixJxh7aXQE1KPdWLDniC24T/6dSnguF33W9j/ZZQcmA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-plugin-utils': 7.21.5 + '@babel/helper-validator-option': 7.21.0 + '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.21.8) + '@babel/plugin-transform-modules-commonjs': 7.21.5(@babel/core@7.21.8) + '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/register@7.21.0(@babel/core@7.21.8): + resolution: {integrity: sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.5 + source-map-support: 0.5.21 + dev: true + + /@babel/regjsgen@0.8.0: + resolution: {integrity: sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA==} + dev: true + + /@babel/runtime@7.21.5: + resolution: {integrity: sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.13.11 + + /@babel/template@7.21.9: + resolution: {integrity: sha512-MK0X5k8NKOuWRamiEfc3KEJiHMTkGZNUjzMipqCGDDc6ijRl/B7RGSKVGncu4Ro/HdyzzY6cmoXuKI2Gffk7vQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.21.4 + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + dev: true + + /@babel/traverse@7.21.5: + resolution: {integrity: sha512-AhQoI3YjWi6u/y/ntv7k48mcrCXmus0t79J9qPNlk/lAsFlCiJ047RmbfMOawySTHtywXhbXgpx/8nXMYd+oFw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.21.4 + '@babel/generator': 7.21.9 + '@babel/helper-environment-visitor': 7.21.5 + '@babel/helper-function-name': 7.21.0 + '@babel/helper-hoist-variables': 7.18.6 + '@babel/helper-split-export-declaration': 7.18.6 + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@babel/types@7.21.5: + resolution: {integrity: sha512-m4AfNvVF2mVC/F7fDEdH2El3HzUg9It/XsCxZiOTTA3m3qYfcSVSbTfM6Q9xG+hYDniZssYhlXKKUMD5m8tF4Q==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.21.5 + '@babel/helper-validator-identifier': 7.19.1 + to-fast-properties: 2.0.0 + + /@colors/colors@1.5.0: + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + requiresBuild: true + dev: true + optional: true + + /@css-render/plugin-bem@0.15.12(css-render@0.15.12): + resolution: {integrity: sha512-Lq2jSOZn+wYQtsyaFj6QRz2EzAnd3iW5fZeHO1WSXQdVYwvwGX0ZiH3X2JQgtgYLT1yeGtrwrqJdNdMEUD2xTw==} + peerDependencies: + css-render: ~0.15.12 + dependencies: + css-render: 0.15.12 + dev: false + + /@css-render/vue3-ssr@0.15.12(vue@3.3.4): + resolution: {integrity: sha512-AQLGhhaE0F+rwybRCkKUdzBdTEM/5PZBYy+fSYe1T9z9+yxMuV/k7ZRqa4M69X+EI1W8pa4kc9Iq2VjQkZx4rg==} + peerDependencies: + vue: ^3.0.11 + dependencies: + vue: 3.3.4 + dev: false + + /@discoveryjs/json-ext@0.5.7: + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + dev: true + + /@emotion/hash@0.8.0: + resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} + dev: false + + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@18.2.0): + resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} + peerDependencies: + react: '>=16.8.0' + dependencies: + react: 18.2.0 + dev: true + + /@esbuild/android-arm64@0.17.19: + resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm@0.17.19: + resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-x64@0.17.19: + resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-arm64@0.17.19: + resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/darwin-x64@0.17.19: + resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-arm64@0.17.19: + resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/freebsd-x64@0.17.19: + resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm64@0.17.19: + resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-arm@0.17.19: + resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ia32@0.17.19: + resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-loong64@0.17.19: + resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-mips64el@0.17.19: + resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-ppc64@0.17.19: + resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-riscv64@0.17.19: + resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-s390x@0.17.19: + resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/linux-x64@0.17.19: + resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@esbuild/netbsd-x64@0.17.19: + resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/openbsd-x64@0.17.19: + resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + + /@esbuild/sunos-x64@0.17.19: + resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-arm64@0.17.19: + resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-ia32@0.17.19: + resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@esbuild/win32-x64@0.17.19: + resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@eslint-community/eslint-utils@4.4.0(eslint@8.41.0): + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + dependencies: + eslint: 8.41.0 + eslint-visitor-keys: 3.4.1 + dev: true + + /@eslint-community/regexpp@4.5.1: + resolution: {integrity: sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + dev: true + + /@eslint/eslintrc@2.0.3: + resolution: {integrity: sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + ajv: 6.12.6 + debug: 4.3.4 + espree: 9.5.2 + globals: 13.20.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@eslint/js@8.41.0: + resolution: {integrity: sha512-LxcyMGxwmTh2lY9FwHPGWOHmYFCZvbrFCBZL4FzSSsxsRPuhrYUg/49/0KDfW8tnIEaEHtfmn6+NPN+1DqaNmA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@fal-works/esbuild-plugin-global-externals@2.1.2: + resolution: {integrity: sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==} + dev: true + + /@headlessui/vue@1.7.13(vue@3.3.4): + resolution: {integrity: sha512-obG5TdPdBDfs+jiA1mY29LPFqyJl93Q90EL86ontfRe1B6XvbjPkx+x1aAC5DA18bXbb0Juni1ayDbXo0w1u0A==} + engines: {node: '>=10'} + peerDependencies: + vue: ^3.2.0 + dependencies: + vue: 3.3.4 + dev: false + + /@humanwhocodes/config-array@0.11.8: + resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} + engines: {node: '>=10.10.0'} + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.3.4 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@humanwhocodes/module-importer@1.0.1: + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + dev: true + + /@humanwhocodes/object-schema@1.2.1: + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + dev: true + + /@icon-park/vue-next@1.4.2(vue@3.3.4): + resolution: {integrity: sha512-+QklF255wkfBOabY+xw6FAI0Bwln/RhdwCunNy/9sKdKuChtaU67QZqU67KGAvZUTeeBgsL+yaHHxqfQeGZXEQ==} + engines: {node: '>= 8.0.0', npm: '>= 5.0.0'} + peerDependencies: + vue: 3.x + dependencies: + vue: 3.3.4 + dev: true + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: true + + /@iconify/utils@2.1.5: + resolution: {integrity: sha512-6MvDI+I6QMvXn5rK9KQGdpEE4mmLTcuQdLZEiX5N+uZB+vc4Yw9K1OtnOgkl8mp4d9X0UrILREyZgF1NUwUt+Q==} + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.2 + '@iconify/types': 2.0.0 + debug: 4.3.4 + kolorist: 1.8.0 + local-pkg: 0.4.3 + transitivePeerDependencies: + - supports-color + dev: true + + /@intlify/bundle-utils@6.0.1(vue-i18n@9.2.2): + resolution: {integrity: sha512-BkeZNKZiC0B7K3OYMwiPLoAqsZmKH3SxTL75vYAkuQ//XWR8WO0NpfjXhTxgLTVFHxMcNb2agAopC0DP6fqDrg==} + engines: {node: '>= 14.16'} + peerDependencies: + petite-vue-i18n: '*' + vue-i18n: '*' + peerDependenciesMeta: + petite-vue-i18n: + optional: true + vue-i18n: + optional: true + dependencies: + '@intlify/message-compiler': 9.3.0-beta.17 + '@intlify/shared': 9.3.0-beta.17 + acorn: 8.8.2 + escodegen: 2.0.0 + estree-walker: 2.0.2 + jsonc-eslint-parser: 1.4.1 + magic-string: 0.30.0 + mlly: 1.2.1 + source-map: 0.6.1 + vue-i18n: 9.2.2(vue@3.3.4) + yaml-eslint-parser: 0.3.2 + dev: true + + /@intlify/core-base@9.2.2: + resolution: {integrity: sha512-JjUpQtNfn+joMbrXvpR4hTF8iJQ2sEFzzK3KIESOx+f+uwIjgw20igOyaIdhfsVVBCds8ZM64MoeNSx+PHQMkA==} + engines: {node: '>= 14'} + dependencies: + '@intlify/devtools-if': 9.2.2 + '@intlify/message-compiler': 9.2.2 + '@intlify/shared': 9.2.2 + '@intlify/vue-devtools': 9.2.2 + + /@intlify/devtools-if@9.2.2: + resolution: {integrity: sha512-4ttr/FNO29w+kBbU7HZ/U0Lzuh2cRDhP8UlWOtV9ERcjHzuyXVZmjyleESK6eVP60tGC9QtQW9yZE+JeRhDHkg==} + engines: {node: '>= 14'} + dependencies: + '@intlify/shared': 9.2.2 + + /@intlify/message-compiler@9.2.2: + resolution: {integrity: sha512-IUrQW7byAKN2fMBe8z6sK6riG1pue95e5jfokn8hA5Q3Bqy4MBJ5lJAofUsawQJYHeoPJ7svMDyBaVJ4d0GTtA==} + engines: {node: '>= 14'} + dependencies: + '@intlify/shared': 9.2.2 + source-map: 0.6.1 + + /@intlify/message-compiler@9.3.0-beta.17: + resolution: {integrity: sha512-i7hvVIRk1Ax2uKa9xLRJCT57to08OhFMhFXXjWN07rmx5pWQYQ23MfX1xgggv9drnWTNhqEiD+u4EJeHoS5+Ww==} + engines: {node: '>= 14'} + dependencies: + '@intlify/shared': 9.3.0-beta.17 + source-map: 0.6.1 + dev: true + + /@intlify/shared@9.2.2: + resolution: {integrity: sha512-wRwTpsslgZS5HNyM7uDQYZtxnbI12aGiBZURX3BTR9RFIKKRWpllTsgzHWvj3HKm3Y2Sh5LPC1r0PDCKEhVn9Q==} + engines: {node: '>= 14'} + + /@intlify/shared@9.3.0-beta.17: + resolution: {integrity: sha512-mscf7RQsUTOil35jTij4KGW1RC9SWQjYScwLxP53Ns6g24iEd5HN7ksbt9O6FvTmlQuX77u+MXpBdfJsGqizLQ==} + engines: {node: '>= 14'} + dev: true + + /@intlify/unplugin-vue-i18n@0.11.0(rollup@2.79.1)(vue-i18n@9.2.2): + resolution: {integrity: sha512-ivcLZo08fvepHWV8o5lcKfhcKFSWqhwrqIAU6pUIbvq2ICo9fnXnIPYIZj7FeuHDLW1G3ADm44ZhQC3nYmvDlg==} + engines: {node: '>= 14.16'} + peerDependencies: + petite-vue-i18n: '*' + vue-i18n: '*' + vue-i18n-bridge: '*' + peerDependenciesMeta: + petite-vue-i18n: + optional: true + vue-i18n: + optional: true + vue-i18n-bridge: + optional: true + dependencies: + '@intlify/bundle-utils': 6.0.1(vue-i18n@9.2.2) + '@intlify/shared': 9.3.0-beta.17 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@vue/compiler-sfc': 3.3.4 + debug: 4.3.4 + fast-glob: 3.2.12 + js-yaml: 4.1.0 + json5: 2.2.3 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + unplugin: 1.3.1 + vue-i18n: 9.2.2(vue@3.3.4) + transitivePeerDependencies: + - rollup + - supports-color + dev: true + + /@intlify/vue-devtools@9.2.2: + resolution: {integrity: sha512-+dUyqyCHWHb/UcvY1MlIpO87munedm3Gn6E9WWYdWrMuYLcoIoOEVDWSS8xSwtlPU+kA+MEQTP6Q1iI/ocusJg==} + engines: {node: '>= 14'} + dependencies: + '@intlify/core-base': 9.2.2 + '@intlify/shared': 9.2.2 + + /@istanbuljs/load-nyc-config@1.1.0: + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + dev: true + + /@istanbuljs/schema@0.1.3: + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + dev: true + + /@jest/schemas@29.4.3: + resolution: {integrity: sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@sinclair/typebox': 0.25.24 + dev: true + + /@jest/transform@29.5.0: + resolution: {integrity: sha512-8vbeZWqLJOvHaDfeMuoHITGKSz5qWc9u04lnWrQE3VyuSw604PzQM824ZeX9XSjUCeDiE3GuxZe5UKa8J61NQw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/core': 7.21.8 + '@jest/types': 29.5.0 + '@jridgewell/trace-mapping': 0.3.18 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.5.0 + jest-regex-util: 29.4.3 + jest-util: 29.5.0 + micromatch: 4.0.5 + pirates: 4.0.5 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@jest/types@27.5.1: + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 18.16.14 + '@types/yargs': 16.0.5 + chalk: 4.1.2 + dev: true + + /@jest/types@29.5.0: + resolution: {integrity: sha512-qbu7kN6czmVRc3xWFQcAN03RAUamgppVUdXrvl1Wr3jlNF93o9mJbGcDWrwGB6ht44u7efB1qCFgVQmca24Uog==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/schemas': 29.4.3 + '@types/istanbul-lib-coverage': 2.0.4 + '@types/istanbul-reports': 3.0.1 + '@types/node': 18.16.14 + '@types/yargs': 17.0.24 + chalk: 4.1.2 + dev: true + + /@jridgewell/gen-mapping@0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} + engines: {node: '>=6.0.0'} + dependencies: + '@jridgewell/set-array': 1.1.2 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@jridgewell/resolve-uri@3.1.0: + resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/set-array@1.1.2: + resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} + engines: {node: '>=6.0.0'} + dev: true + + /@jridgewell/source-map@0.3.5: + resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==} + dependencies: + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + dev: true + + /@jridgewell/sourcemap-codec@1.4.14: + resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} + dev: true + + /@jridgewell/sourcemap-codec@1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + + /@jridgewell/trace-mapping@0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} + dependencies: + '@jridgewell/resolve-uri': 3.1.0 + '@jridgewell/sourcemap-codec': 1.4.14 + dev: true + + /@juggle/resize-observer@3.4.0: + resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} + + /@mdx-js/react@2.3.0(react@18.2.0): + resolution: {integrity: sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==} + peerDependencies: + react: '>=16' + dependencies: + '@types/mdx': 2.0.5 + '@types/react': 18.2.6 + react: 18.2.0 + dev: true + + /@ndelangen/get-tarball@3.0.7: + resolution: {integrity: sha512-NqGfTZIZpRFef1GoVaShSSRwDC3vde3ThtTeqFdcYd6ipKqnfEVhjK2hUeHjCQUcptyZr2TONqcloFXM+5QBrQ==} + dependencies: + gunzip-maybe: 1.4.2 + pump: 3.0.0 + tar-fs: 2.1.1 + dev: true + + /@nodelib/fs.scandir@2.1.5: + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + dev: true + + /@nodelib/fs.stat@2.0.5: + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + dev: true + + /@nodelib/fs.walk@1.2.8: + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.15.0 + dev: true + + /@polka/url@1.0.0-next.21: + resolution: {integrity: sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==} + dev: true + + /@rollup/plugin-babel@5.3.1(@babel/core@7.21.8)(rollup@2.79.1): + resolution: {integrity: sha512-WFfdLWU/xVWKeRQnKmIAQULUI7Il0gZnBIH/ZFO069wYIfPu+8zrfp/KMW0atmELoRDq8FbiP3VCss9MhCut7Q==} + engines: {node: '>= 10.0.0'} + peerDependencies: + '@babel/core': ^7.0.0 + '@types/babel__core': ^7.1.9 + rollup: ^1.20.0||^2.0.0 + peerDependenciesMeta: + '@types/babel__core': + optional: true + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-module-imports': 7.21.4 + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + rollup: 2.79.1 + dev: true + + /@rollup/plugin-node-resolve@11.2.1(rollup@2.79.1): + resolution: {integrity: sha512-yc2n43jcqVyGE2sqV5/YCmocy9ArjVAP/BeXyTtADTBBX6V0e5UMqwO8CdQ0kzjb6zu5P1qMzsScCMRvE9OlVg==} + engines: {node: '>= 10.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + '@types/resolve': 1.17.1 + builtin-modules: 3.3.0 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.2 + rollup: 2.79.1 + dev: true + + /@rollup/plugin-replace@2.4.2(rollup@2.79.1): + resolution: {integrity: sha512-IGcu+cydlUMZ5En85jxHH4qj2hta/11BHq95iHEyb2sbgiN0eCdzvUcHw5gt9pBL5lTi4JDYJ1acCoMGpTvEZg==} + peerDependencies: + rollup: ^1.20.0 || ^2.0.0 + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@2.79.1) + magic-string: 0.25.9 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@3.1.0(rollup@2.79.1): + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@rollup/pluginutils@4.2.1: + resolution: {integrity: sha512-iKnFXr7NkdZAIHiIWE+BX5ULi/ucVFYWD6TbAV+rZctiRTY2PL6tsIKhoIOaoskiWAkgu+VsbXgUVDNLHf+InQ==} + engines: {node: '>= 8.0.0'} + dependencies: + estree-walker: 2.0.2 + picomatch: 2.3.1 + dev: true + + /@rollup/pluginutils@5.0.2(rollup@2.79.1): + resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + dependencies: + '@types/estree': 1.0.1 + estree-walker: 2.0.2 + picomatch: 2.3.1 + rollup: 2.79.1 + dev: true + + /@sinclair/typebox@0.25.24: + resolution: {integrity: sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==} + dev: true + + /@storybook/addon-actions@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-f07Mc3qwcG9heGsuUUTIJbWF2nw/Ite3mvyIZY2VbgwhMUMVHj4knY4fh/LojwcUmmmc7CNZu3sJN/wIqpaHCQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + dequal: 2.0.3 + lodash: 4.17.21 + polished: 4.2.2 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + react-inspector: 6.0.1(react@18.2.0) + telejson: 7.1.0 + ts-dedent: 2.2.0 + uuid: 9.0.0 + dev: true + + /@storybook/addon-backgrounds@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-sAZSxsbj3CcabowALKTafpdnqXMBZB8C42s4Uxv11FCP50GqrP8jp2TqsIiDZxUbeXwI094W/gHnw41MSphG8Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-controls@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-/+yBhswN1N7ttR1NGN94HE/25VELm4YuBtrkh+LJeKP/eQ5CZpLjexASN2GZcfmdnkwIYZAEH0X/AImLaCJAWA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/blocks': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.0.12 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.0.12 + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + lodash: 4.17.21 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/addon-docs@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-zgg4sq34Zz8TN74+kSogxRHsIZ5gsIazJpa0osZp91nJQvsKUEfldjBtQWbBWzjVCrWmzOhW5/RLCnmCNm9y/w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@babel/core': 7.21.8 + '@babel/plugin-transform-react-jsx': 7.21.5(@babel/core@7.21.8) + '@jest/transform': 29.5.0 + '@mdx-js/react': 2.3.0(react@18.2.0) + '@storybook/blocks': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/csf-plugin': 7.0.12 + '@storybook/csf-tools': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/mdx2-csf': 1.1.0 + '@storybook/node-logger': 7.0.12 + '@storybook/postinstall': 7.0.12 + '@storybook/preview-api': 7.0.12 + '@storybook/react-dom-shim': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + fs-extra: 11.1.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + remark-external-links: 8.0.0 + remark-slug: 6.1.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/addon-essentials@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Js2cxvauAf8fkA5D0QrqPPe/FvpY1DbJp61VNGh82Xu0zZrczCGYP3jkWG79vl0zllJNs7hnkV8W6xY1JWgLoA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/addon-actions': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-backgrounds': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-controls': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-docs': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-highlight': 7.0.12 + '@storybook/addon-measure': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-outline': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-toolbars': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/addon-viewport': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.0.12 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/node-logger': 7.0.12 + '@storybook/preview-api': 7.0.12 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/addon-highlight@7.0.12: + resolution: {integrity: sha512-ccIsBVjUlZ7cM1adSSFTqqWXiELPdDqfZLz4dWfDbiLyG3InC953ugtvoUWCIZpC2OOnjVLpF7Rbshq2O/QoMw==} + dependencies: + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 7.0.12 + dev: true + + /@storybook/addon-interactions@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Rb1mv1RQrTd3sA/WwNTdv00rW+7APfvZEeZks6+8+kS1C4EFMDmLnVBZlPllFdo1BOnTCyer4GZZ5ncVkWNLyQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-common': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/instrumenter': 7.0.12 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + jest-mock: 27.5.1 + polished: 4.2.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/addon-links@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6kGClsIpX9dRKc5bUAPNcp/4wlgPIxMrieUV+6k1dTsRQqbaEfxih/Fq259D5+yVBDNi3YAnvRjMiIibl8fa5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/router': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-measure@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-Uq9cj9QmN7WKBQ6wqeneFmTqo1UQKXIc4CpGBEtJtfsYNLsERrVzOs/tRUf66Zl3lWgfFZxs1B5Ij6RDsYEjRw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/types': 7.0.12 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/addon-outline@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-eZPkm3mECdqx1EDJ0S6DAzZ9WZLPIsZH7fRy6vdJJuAgvnOSzkt7AEpA0hlgiNyXcFpE1Cav6/g12FUf4Zo82g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/types': 7.0.12 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + ts-dedent: 2.2.0 + dev: true + + /@storybook/addon-toolbars@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-7xRxk+999NVdEwzn2z1O9Tg5iuUSEXQ5jo+hiyK934VvuyqUsZnflKbSvwVEHb2W+DroaaXu8bdHWxGSH+6moQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/addon-viewport@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-pMgqtDQF8e9AErnRKbbSK9m1lcKn1dFSOkk0PgSBwIIjmha6q+GeT45EHQrQGtkLdtWT0iTktC8ivzIiGKmHkg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + memoizerific: 1.11.3 + prop-types: 15.8.1 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/blocks@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-MbJKjuTJ7xVbkUVwkEwb6vTYGrkRk4+Xtx1UGo+512o91ubqFs8hXwCHP+x/49RCIIQs5zl93Ig8fTtm+MejWw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/components': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/core-events': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/docs-tools': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/manager-api': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/preview-api': 7.0.12 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + '@types/lodash': 4.14.194 + color-convert: 2.0.1 + dequal: 2.0.3 + lodash: 4.17.21 + markdown-to-jsx: 7.2.0(react@18.2.0) + memoizerific: 1.11.3 + polished: 4.2.2 + react: 18.2.0 + react-colorful: 5.6.1(react-dom@18.2.0)(react@18.2.0) + react-dom: 18.2.0(react@18.2.0) + telejson: 7.1.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/builder-manager@7.0.12: + resolution: {integrity: sha512-bkZPSDH38/dUSsO087oQ8+goyaEDP/xD0/O61QcQ8EbaVeT6s6Qt7mMhqsLrtmEZHvPMQwKeIXhOJlRNNXB+SA==} + dependencies: + '@fal-works/esbuild-plugin-global-externals': 2.1.2 + '@storybook/core-common': 7.0.12 + '@storybook/manager': 7.0.12 + '@storybook/node-logger': 7.0.12 + '@types/ejs': 3.1.2 + '@types/find-cache-dir': 3.2.1 + '@yarnpkg/esbuild-plugin-pnp': 3.0.0-rc.15(esbuild@0.17.19) + browser-assert: 1.2.1 + ejs: 3.1.9 + esbuild: 0.17.19 + esbuild-plugin-alias: 0.2.1 + express: 4.18.2 + find-cache-dir: 3.3.2 + fs-extra: 11.1.1 + process: 0.11.10 + util: 0.12.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/builder-vite@7.0.12(typescript@4.9.5)(vite@4.3.5): + resolution: {integrity: sha512-6FJNXis+dYs/KrhfRQgz8HcRw/Oq4FaEghCwsjngQDy4PcpQuxkDbvGJKlBaSr92vUL36FWSPq8u5+VGCHjh5Q==} + peerDependencies: + '@preact/preset-vite': '*' + typescript: '>= 4.3.x' + vite: ^3.0.0 || ^4.0.0 + vite-plugin-glimmerx: '*' + peerDependenciesMeta: + '@preact/preset-vite': + optional: true + typescript: + optional: true + vite-plugin-glimmerx: + optional: true + dependencies: + '@storybook/channel-postmessage': 7.0.12 + '@storybook/channel-websocket': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/core-common': 7.0.12 + '@storybook/csf-plugin': 7.0.12 + '@storybook/mdx2-csf': 1.1.0 + '@storybook/node-logger': 7.0.12 + '@storybook/preview': 7.0.12 + '@storybook/preview-api': 7.0.12 + '@storybook/types': 7.0.12 + browser-assert: 1.2.1 + es-module-lexer: 0.9.3 + express: 4.18.2 + fs-extra: 11.1.1 + glob: 8.1.0 + glob-promise: 6.0.2(glob@8.1.0) + magic-string: 0.27.0 + remark-external-links: 8.0.0 + remark-slug: 6.1.0 + rollup: 3.23.0 + typescript: 4.9.5 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/channel-postmessage@7.0.12: + resolution: {integrity: sha512-Tc7kQZ5yxlZ44Nmmzec92JaDJ6UZ3Ze4cBfiHik4XcnM1PtN8hr8VFoC6a2AIm1ybfIRenfT5w9TH5yriiPIhw==} + dependencies: + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + qs: 6.11.2 + telejson: 7.1.0 + dev: true + + /@storybook/channel-websocket@7.0.12: + resolution: {integrity: sha512-UV6b9gX2mQLtXlKaFKCHcy+6MaK2od6BYqSJfainnBjDsMIXyhcf7fJaj0XQkJrbNnRBwGhw+6s8JxL98xp7Ew==} + dependencies: + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/global': 5.0.0 + telejson: 7.1.0 + dev: true + + /@storybook/channels@7.0.12: + resolution: {integrity: sha512-KDdDmDs8kxAJU+vndTqTNazjLO+XoIPiTRlfP7mk7cgHiQXSjMYy3JSCQ7W0of0Q+9VSl/ve9CNbnGbcQF7rNQ==} + dev: true + + /@storybook/cli@7.0.12: + resolution: {integrity: sha512-OABCRIujxsszIJ0CCpKg8Uj4C1UlAwBpBQhv2aMX3lA/pur6Od524syv2ypWu6J2FyvK/ooeyMbjoP7330cIuA==} + hasBin: true + dependencies: + '@babel/core': 7.21.8 + '@babel/preset-env': 7.21.5(@babel/core@7.21.8) + '@ndelangen/get-tarball': 3.0.7 + '@storybook/codemod': 7.0.12 + '@storybook/core-common': 7.0.12 + '@storybook/core-server': 7.0.12 + '@storybook/csf-tools': 7.0.12 + '@storybook/node-logger': 7.0.12 + '@storybook/telemetry': 7.0.12 + '@storybook/types': 7.0.12 + '@types/semver': 7.5.0 + boxen: 5.1.2 + chalk: 4.1.2 + commander: 6.2.1 + cross-spawn: 7.0.3 + detect-indent: 6.1.0 + envinfo: 7.8.1 + execa: 5.1.1 + express: 4.18.2 + find-up: 5.0.0 + fs-extra: 11.1.1 + get-npm-tarball-url: 2.0.3 + get-port: 5.1.1 + giget: 1.1.2 + globby: 11.1.0 + jscodeshift: 0.14.0(@babel/preset-env@7.21.5) + leven: 3.1.0 + prettier: 2.8.8 + prompts: 2.4.2 + puppeteer-core: 2.1.1 + read-pkg-up: 7.0.1 + semver: 7.5.1 + shelljs: 0.8.5 + simple-update-notifier: 1.1.0 + strip-json-comments: 3.1.1 + tempy: 1.0.1 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /@storybook/client-logger@7.0.12: + resolution: {integrity: sha512-MQMtIgGEgdixvxnBvZ2m8hhc0DGJWeCpHtxg7oqBLBEBmCYFueTqDZHl4Z6SoCrK0a2YS5X/BIXOcEtP1ulMKw==} + dependencies: + '@storybook/global': 5.0.0 + dev: true + + /@storybook/codemod@7.0.12: + resolution: {integrity: sha512-eGbGZSglvbnY1omzRyEC4XP0FbpuCFKgjXmdHn9faGQUU5EJHwcGYYrRW8JZL3nEVIvNDuRAKzM3p0BVo1xeSQ==} + dependencies: + '@babel/core': 7.21.8 + '@babel/preset-env': 7.21.5(@babel/core@7.21.8) + '@babel/types': 7.21.5 + '@storybook/csf': 0.1.0 + '@storybook/csf-tools': 7.0.12 + '@storybook/node-logger': 7.0.12 + '@storybook/types': 7.0.12 + cross-spawn: 7.0.3 + globby: 11.1.0 + jscodeshift: 0.14.0(@babel/preset-env@7.21.5) + lodash: 4.17.21 + prettier: 2.8.8 + recast: 0.23.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/components@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-6TxByzYS4+LxwZRioGpP6Zh9If5ctjQs5OnR2UmQvP6HDjmMWYTntoHKIbDwAL9C6MrnQYpPOGCPkqrtODQ4/w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + use-resize-observer: 9.1.0(react-dom@18.2.0)(react@18.2.0) + util-deprecate: 1.0.2 + dev: true + + /@storybook/core-client@7.0.12: + resolution: {integrity: sha512-m0r+Vl3LfU8cJl8UqIwzh0sEN9I//nMaT8UIIm481AINhQTNihQcnYi9jRw7USjfz2fv5CYkg8cEr4KhI8QlRA==} + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/preview-api': 7.0.12 + dev: true + + /@storybook/core-common@7.0.12: + resolution: {integrity: sha512-PFVjYXHUxDQO1oqfqwQe7S3XoLNO0aZYEr9Zl0LiexlxxnU1v+TQjEfNd/H3T0xxpXlsgzhtEcagdzJeAKyh2g==} + dependencies: + '@storybook/node-logger': 7.0.12 + '@storybook/types': 7.0.12 + '@types/node': 16.18.32 + '@types/pretty-hrtime': 1.0.1 + chalk: 4.1.2 + esbuild: 0.17.19 + esbuild-register: 3.4.2(esbuild@0.17.19) + file-system-cache: 2.3.0 + find-up: 5.0.0 + fs-extra: 11.1.1 + glob: 8.1.0 + glob-promise: 6.0.2(glob@8.1.0) + handlebars: 4.7.7 + lazy-universal-dotenv: 4.0.0 + picomatch: 2.3.1 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + resolve-from: 5.0.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/core-events@7.0.12: + resolution: {integrity: sha512-VTmb/zjbz3o1bg+bATzLigVXMVDC/S1FP8CqIrz4mkiys52139FGzMandL2Y2AecPZPGss7ZRdfma28HKVYTRg==} + dev: true + + /@storybook/core-server@7.0.12: + resolution: {integrity: sha512-X35Kmg7y35Ph4J+gCDJrnVgBwlz4/DzOQofUS6rAbi4KvrPWDJXeM2OzOgx6B0abKl4CeMmjuc0tjbg4vbUFuA==} + dependencies: + '@aw-web-design/x-default-browser': 1.4.88 + '@discoveryjs/json-ext': 0.5.7 + '@storybook/builder-manager': 7.0.12 + '@storybook/core-common': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/csf-tools': 7.0.12 + '@storybook/docs-mdx': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/manager': 7.0.12 + '@storybook/node-logger': 7.0.12 + '@storybook/preview-api': 7.0.12 + '@storybook/telemetry': 7.0.12 + '@storybook/types': 7.0.12 + '@types/detect-port': 1.3.2 + '@types/node': 16.18.32 + '@types/node-fetch': 2.6.4 + '@types/pretty-hrtime': 1.0.1 + '@types/semver': 7.5.0 + better-opn: 2.1.1 + boxen: 5.1.2 + chalk: 4.1.2 + cli-table3: 0.6.3 + compression: 1.7.4 + detect-port: 1.5.1 + express: 4.18.2 + fs-extra: 11.1.1 + globby: 11.1.0 + ip: 2.0.0 + lodash: 4.17.21 + node-fetch: 2.6.11 + open: 8.4.2 + pretty-hrtime: 1.0.3 + prompts: 2.4.2 + read-pkg-up: 7.0.1 + semver: 7.5.1 + serve-favicon: 2.5.0 + telejson: 7.1.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + watchpack: 2.4.0 + ws: 8.13.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /@storybook/csf-plugin@7.0.12: + resolution: {integrity: sha512-iiH0ynLQV5BYFc0o7RlSJS2S3GT/ffyfbV4rnCnPKdqyo4REEVvmhOuLhwzurtsXsjh+xF6VUYUDN+8/5mbkYw==} + dependencies: + '@storybook/csf-tools': 7.0.12 + unplugin: 0.10.2 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/csf-tools@7.0.12: + resolution: {integrity: sha512-EcDzKeENzs4awyjx0VxlONDLibiEtIPDP1XdOCcZGtv3nXXBFtS2WDsYhJHkwyvE37jWTyw2e4xKQmBi0Hjvbw==} + dependencies: + '@babel/generator': 7.21.9 + '@babel/parser': 7.21.9 + '@babel/traverse': 7.21.5 + '@babel/types': 7.21.5 + '@storybook/csf': 0.1.0 + '@storybook/types': 7.0.12 + fs-extra: 11.1.1 + recast: 0.23.2 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/csf@0.0.1: + resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} + dependencies: + lodash: 4.17.21 + dev: true + + /@storybook/csf@0.1.0: + resolution: {integrity: sha512-uk+jMXCZ8t38jSTHk2o5btI+aV2Ksbvl6DoOv3r6VaCM1KZqeuMwtwywIQdflkA8/6q/dKT8z8L+g8hC4GC3VQ==} + dependencies: + type-fest: 2.19.0 + dev: true + + /@storybook/docs-mdx@0.1.0: + resolution: {integrity: sha512-JDaBR9lwVY4eSH5W8EGHrhODjygPd6QImRbwjAuJNEnY0Vw4ie3bPkeGfnacB3OBW6u/agqPv2aRlR46JcAQLg==} + dev: true + + /@storybook/docs-tools@7.0.12: + resolution: {integrity: sha512-+HykeQLgjyDyF9G7HqY0FHXlX7X5YpQcmNjftJzBrc/GO1EeO0M78d54avcOPyyTfuWOh7oZtSJ0MzjA1qrqaQ==} + dependencies: + '@babel/core': 7.21.8 + '@storybook/core-common': 7.0.12 + '@storybook/preview-api': 7.0.12 + '@storybook/types': 7.0.12 + '@types/doctrine': 0.0.3 + doctrine: 3.0.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /@storybook/global@5.0.0: + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + dev: true + + /@storybook/instrumenter@7.0.12: + resolution: {integrity: sha512-jx4rb4AMT1YIOpE0HCdfyLvpYU+94wPkC9vt7sZGWAp7nnYG+KO/lx3XCJaR9qQPIxVYejJtWkeGn4RID79SoQ==} + dependencies: + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 7.0.12 + dev: true + + /@storybook/manager-api@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3QXARtxpc6Xxqf5pviUw2UuhK53+IsINSljeWhAqdQ1Gzbywl67TpibTd7xVN6NKxhUH5Bzo9bIZTAzMZGqaKw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/router': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/theming': 7.0.12(react-dom@18.2.0)(react@18.2.0) + '@storybook/types': 7.0.12 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + semver: 7.5.1 + store2: 2.14.2 + telejson: 7.1.0 + ts-dedent: 2.2.0 + dev: true + + /@storybook/manager@7.0.12: + resolution: {integrity: sha512-19BsDcwJOYXn6zEarxvNGDdYLUqZyhX92x6GPHSC4cf8BoxHuhmtnz5vOTZHusCxkKIu/C9W0H6wH2Ma47kDCg==} + dev: true + + /@storybook/mdx2-csf@1.1.0: + resolution: {integrity: sha512-TXJJd5RAKakWx4BtpwvSNdgTDkKM6RkXU8GK34S/LhidQ5Pjz3wcnqb0TxEkfhK/ztbP8nKHqXFwLfa2CYkvQw==} + dev: true + + /@storybook/node-logger@7.0.12: + resolution: {integrity: sha512-VL+NXzc9NuOP6/9alg4Sofz9kh8tmlo3p+UtCIYCHH088yCsB3XsNhkG9lF1C5EZVWcuHxc2u6MMF3ezOjvKfQ==} + dependencies: + '@types/npmlog': 4.1.4 + chalk: 4.1.2 + npmlog: 5.0.1 + pretty-hrtime: 1.0.3 + dev: true + + /@storybook/postinstall@7.0.12: + resolution: {integrity: sha512-RKNvBLgABBTQwvGyF2jX4vP7OMLB3KvEEOQDoeOKjqyWfekDn5smI+eT714mtmKIH0YMcwmvzLgEdZkjmM/XhA==} + dev: true + + /@storybook/preview-api@7.0.12: + resolution: {integrity: sha512-YI/AfHszIOYt967fsRlc7j6I0zZB+RSsBwD/nMA8y9vszdpQ0MgRhxHgQxFf6cgqbuQcdCsnTIpT0iQ4GHjDXg==} + dependencies: + '@storybook/channel-postmessage': 7.0.12 + '@storybook/channels': 7.0.12 + '@storybook/client-logger': 7.0.12 + '@storybook/core-events': 7.0.12 + '@storybook/csf': 0.1.0 + '@storybook/global': 5.0.0 + '@storybook/types': 7.0.12 + '@types/qs': 6.9.7 + dequal: 2.0.3 + lodash: 4.17.21 + memoizerific: 1.11.3 + qs: 6.11.2 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + dev: true + + /@storybook/preview@7.0.12: + resolution: {integrity: sha512-za8El/nnkyAo/uqyqAg7PMuP6DSdPoEnDRyIk4LzY7sAGly6i4Uge377cdo1nUBQLS5S4kKIc4xf8TUegb3G1Q==} + dev: true + + /@storybook/react-dom-shim@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-4z9J54TD7uphxPqSuLEzeKTV4oF8Fmv8qFfnT0XZJ2mpYTC2NTbkYoYZQ8N0eYzvNOk6xgfpDqBdmIANf4NaYw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/router@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-dOtBiCBGeDem86BCWR7AlTVQjoBk0yw/XZLXS9qcpUfpe+UDjd0Rh21ZdEEMHG1Wfu4d2AhhG5l/JSJ1IE83jQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@storybook/client-logger': 7.0.12 + memoizerific: 1.11.3 + qs: 6.11.2 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/telemetry@7.0.12: + resolution: {integrity: sha512-oxqe15bn5W+1pLpLjXTfj3H+YPZq3jExjdJwTCUHtFrrsNs0k6dyqAUk8qTOUqOTclANHb6vlNBFJDvZ6qbfEQ==} + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/core-common': 7.0.12 + chalk: 4.1.2 + detect-package-manager: 2.0.1 + fetch-retry: 5.0.6 + fs-extra: 11.1.1 + isomorphic-unfetch: 3.1.0 + nanoid: 3.3.6 + read-pkg-up: 7.0.1 + transitivePeerDependencies: + - encoding + - supports-color + dev: true + + /@storybook/testing-library@0.0.14-next.2: + resolution: {integrity: sha512-i/SLSGm0o978ELok/SB4Qg1sZ3zr+KuuCkzyFqcCD0r/yf+bG35aQGkFqqxfSAdDxuQom0NO02FE+qys5Eapdg==} + dependencies: + '@storybook/client-logger': 7.0.12 + '@storybook/instrumenter': 7.0.12 + '@testing-library/dom': 8.20.0 + '@testing-library/user-event': 13.5.0(@testing-library/dom@8.20.0) + ts-dedent: 2.2.0 + dev: true + + /@storybook/theming@7.0.12(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-frBkvH7LF8j23ODaywLK4m4LLscw49oKblkZ+30QZkBAzRf2o3a/QSZW2V1zfBo7ygcXiUJ5bIjh7Y17mMJqbQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + dependencies: + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) + '@storybook/client-logger': 7.0.12 + '@storybook/global': 5.0.0 + memoizerific: 1.11.3 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /@storybook/types@7.0.12: + resolution: {integrity: sha512-nlvU4MyO2grwPCRQ8alA3AnY1bQxGJ6A4QgJu+1MhtjVenifFlxOQX4H1OiA+YXfjlV096oO5LrxvetJPFAKKQ==} + dependencies: + '@storybook/channels': 7.0.12 + '@types/babel__core': 7.20.0 + '@types/express': 4.17.17 + file-system-cache: 2.3.0 + dev: true + + /@storybook/vue3-vite@7.0.12(react-dom@18.2.0)(react@18.2.0)(typescript@4.9.5)(vite@4.3.5)(vue@3.3.4): + resolution: {integrity: sha512-SdAGfBRfm4cR9VNLRcBCLo3rTzeUTvZfyh5ll0cgInCo9gTxwfs1Y4zEmmVqDDOWQ7qlpJanITNGFGiSsdvRmg==} + engines: {node: ^14.18 || >=16} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + vite: ^3.0.0 || ^4.0.0 + dependencies: + '@storybook/builder-vite': 7.0.12(typescript@4.9.5)(vite@4.3.5) + '@storybook/core-server': 7.0.12 + '@storybook/vue3': 7.0.12(vue@3.3.4) + '@vitejs/plugin-vue': 4.2.3(vite@4.3.5)(vue@3.3.4) + magic-string: 0.27.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + vue-docgen-api: 4.72.3(vue@3.3.4) + transitivePeerDependencies: + - '@preact/preset-vite' + - bufferutil + - encoding + - supports-color + - typescript + - utf-8-validate + - vite-plugin-glimmerx + - vue + dev: true + + /@storybook/vue3@7.0.12(vue@3.3.4): + resolution: {integrity: sha512-zxRhuuNcM9hT1/s968iHL+diqFqRmpwvEoI7rF1yje09saMck+PFStlE8b/ohQeDtm0GdwVqjbzfHZIdPbivYg==} + engines: {node: '>=16.0.0'} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@storybook/core-client': 7.0.12 + '@storybook/docs-tools': 7.0.12 + '@storybook/global': 5.0.0 + '@storybook/preview-api': 7.0.12 + '@storybook/types': 7.0.12 + ts-dedent: 2.2.0 + type-fest: 2.19.0 + vue: 3.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /@surma/rollup-plugin-off-main-thread@2.2.3: + resolution: {integrity: sha512-lR8q/9W7hZpMWweNiAKU7NQerBnzQQLvi8qnTDU/fxItPhtZVMbPV3lbCwjhIlNBe9Bbr5V+KHshvWmVSG9cxQ==} + dependencies: + ejs: 3.1.9 + json5: 2.2.3 + magic-string: 0.25.9 + string.prototype.matchall: 4.0.8 + dev: true + + /@testing-library/dom@8.20.0: + resolution: {integrity: sha512-d9ULIT+a4EXLX3UU8FBjauG9NnsZHkHztXoIcTsOKoOw030fyjheN9svkTULjJxtYag9DZz5Jz5qkWZDPxTFwA==} + engines: {node: '>=12'} + dependencies: + '@babel/code-frame': 7.21.4 + '@babel/runtime': 7.21.5 + '@types/aria-query': 5.0.1 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + dev: true + + /@testing-library/user-event@13.5.0(@testing-library/dom@8.20.0): + resolution: {integrity: sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + dependencies: + '@babel/runtime': 7.21.5 + '@testing-library/dom': 8.20.0 + dev: true + + /@types/aria-query@5.0.1: + resolution: {integrity: sha512-XTIieEY+gvJ39ChLcB4If5zHtPxt3Syj5rgZR+e1ctpmK8NjPf0zFqsz4JpLJT0xla9GFDKjy8Cpu331nrmE1Q==} + dev: true + + /@types/babel__core@7.20.0: + resolution: {integrity: sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ==} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + '@types/babel__generator': 7.6.4 + '@types/babel__template': 7.4.1 + '@types/babel__traverse': 7.18.5 + dev: true + + /@types/babel__generator@7.6.4: + resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@types/babel__template@7.4.1: + resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + dev: true + + /@types/babel__traverse@7.18.5: + resolution: {integrity: sha512-enCvTL8m/EHS/zIvJno9nE+ndYPh1/oNFzRYRmtUqJICG2VnCSBzMLW5VN2KCQU91f23tsNKR8v7VJJQMatl7Q==} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /@types/body-parser@1.19.2: + resolution: {integrity: sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==} + dependencies: + '@types/connect': 3.4.35 + '@types/node': 18.16.14 + dev: true + + /@types/chai-subset@1.3.3: + resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} + dependencies: + '@types/chai': 4.3.5 + dev: true + + /@types/chai@4.3.5: + resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} + dev: true + + /@types/connect@3.4.35: + resolution: {integrity: sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==} + dependencies: + '@types/node': 18.16.14 + dev: true + + /@types/detect-port@1.3.2: + resolution: {integrity: sha512-xxgAGA2SAU4111QefXPSp5eGbDm/hW6zhvYl9IeEPZEry9F4d66QAHm5qpUXjb6IsevZV/7emAEx5MhP6O192g==} + dev: true + + /@types/doctrine@0.0.3: + resolution: {integrity: sha512-w5jZ0ee+HaPOaX25X2/2oGR/7rgAQSYII7X7pp0m9KgBfMP7uKfMfTvcpl5Dj+eDBbpxKGiqE+flqDr6XTd2RA==} + dev: true + + /@types/ejs@3.1.2: + resolution: {integrity: sha512-ZmiaE3wglXVWBM9fyVC17aGPkLo/UgaOjEiI2FXQfyczrCefORPxIe+2dVmnmk3zkVIbizjrlQzmPGhSYGXG5g==} + dev: true + + /@types/estree@0.0.39: + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + dev: true + + /@types/estree@1.0.1: + resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} + dev: true + + /@types/express-serve-static-core@4.17.35: + resolution: {integrity: sha512-wALWQwrgiB2AWTT91CB62b6Yt0sNHpznUXeZEcnPU3DRdlDIz74x8Qg1UUYKSVFi+va5vKOLYRBI1bRKiLLKIg==} + dependencies: + '@types/node': 18.16.14 + '@types/qs': 6.9.7 + '@types/range-parser': 1.2.4 + '@types/send': 0.17.1 + dev: true + + /@types/express@4.17.17: + resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + dependencies: + '@types/body-parser': 1.19.2 + '@types/express-serve-static-core': 4.17.35 + '@types/qs': 6.9.7 + '@types/serve-static': 1.15.1 + dev: true + + /@types/find-cache-dir@3.2.1: + resolution: {integrity: sha512-frsJrz2t/CeGifcu/6uRo4b+SzAwT4NYCVPu1GN8IB9XTzrpPkGuV0tmh9mN+/L0PklAlsC3u5Fxt0ju00LXIw==} + dev: true + + /@types/glob@8.1.0: + resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 18.16.14 + dev: true + + /@types/graceful-fs@4.1.6: + resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==} + dependencies: + '@types/node': 18.16.14 + dev: true + + /@types/istanbul-lib-coverage@2.0.4: + resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} + dev: true + + /@types/istanbul-lib-report@3.0.0: + resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} + dependencies: + '@types/istanbul-lib-coverage': 2.0.4 + dev: true + + /@types/istanbul-reports@3.0.1: + resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==} + dependencies: + '@types/istanbul-lib-report': 3.0.0 + dev: true + + /@types/json-schema@7.0.11: + resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + dev: true + + /@types/json5@0.0.29: + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + dev: true + + /@types/katex@0.14.0: + resolution: {integrity: sha512-+2FW2CcT0K3P+JMR8YG846bmDwplKUTsWgT2ENwdQ1UdVfRk3GQrh6Mi4sTopy30gI8Uau5CEqHTDZ6YvWIUPA==} + dev: false + + /@types/lodash-es@4.17.7: + resolution: {integrity: sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ==} + dependencies: + '@types/lodash': 4.14.194 + dev: false + + /@types/lodash@4.14.194: + resolution: {integrity: sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g==} + + /@types/mdast@3.0.11: + resolution: {integrity: sha512-Y/uImid8aAwrEA24/1tcRZwpxX3pIFTSilcNDKSPn+Y2iDywSEachzRuvgAYYLR3wpGXAsMbv5lvKLDZLeYPAw==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /@types/mdx@2.0.5: + resolution: {integrity: sha512-76CqzuD6Q7LC+AtbPqrvD9AqsN0k8bsYo2bM2J8pmNldP1aIPAbzUQ7QbobyXL4eLr1wK5x8FZFe8eF/ubRuBg==} + dev: true + + /@types/mime-types@2.1.1: + resolution: {integrity: sha512-vXOTGVSLR2jMw440moWTC7H19iUyLtP3Z1YTj7cSsubOICinjMxFeb/V57v9QdyyPGbbWolUFSSmSiRSn94tFw==} + dev: true + + /@types/mime@1.3.2: + resolution: {integrity: sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==} + dev: true + + /@types/mime@3.0.1: + resolution: {integrity: sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA==} + dev: true + + /@types/minimatch@5.1.2: + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + dev: true + + /@types/node-fetch@2.6.4: + resolution: {integrity: sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==} + dependencies: + '@types/node': 18.16.14 + form-data: 3.0.1 + dev: true + + /@types/node@16.18.32: + resolution: {integrity: sha512-zpnXe4dEz6PrWz9u7dqyRoq9VxwCvoXRPy/ewhmMa1CgEyVmtL1NJPQ2MX+4pf97vetquVKkpiMx0MwI8pjNOw==} + dev: true + + /@types/node@18.16.14: + resolution: {integrity: sha512-+ImzUB3mw2c5ISJUq0punjDilUQ5GnUim0ZRvchHIWJmOC0G+p0kzhXBqj6cDjK0QdPFwzrHWgrJp3RPvCG5qg==} + dev: true + + /@types/normalize-package-data@2.4.1: + resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} + dev: true + + /@types/npmlog@4.1.4: + resolution: {integrity: sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ==} + dev: true + + /@types/pretty-hrtime@1.0.1: + resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==} + dev: true + + /@types/prop-types@15.7.5: + resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} + dev: true + + /@types/qs@6.9.7: + resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} + dev: true + + /@types/range-parser@1.2.4: + resolution: {integrity: sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==} + dev: true + + /@types/react@18.2.6: + resolution: {integrity: sha512-wRZClXn//zxCFW+ye/D2qY65UsYP1Fpex2YXorHc8awoNamkMZSvBxwxdYVInsHOZZd2Ppq8isnSzJL5Mpf8OA==} + dependencies: + '@types/prop-types': 15.7.5 + '@types/scheduler': 0.16.3 + csstype: 3.1.2 + dev: true + + /@types/resolve@1.17.1: + resolution: {integrity: sha512-yy7HuzQhj0dhGpD8RLXSZWEkLsV9ibvxvi6EiJ3bkqLAO1RGo0WbkWQiwpRlSFymTJRz0d3k5LM3kkx8ArDbLw==} + dependencies: + '@types/node': 18.16.14 + dev: true + + /@types/scheduler@0.16.3: + resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} + dev: true + + /@types/semver@7.5.0: + resolution: {integrity: sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==} + dev: true + + /@types/send@0.17.1: + resolution: {integrity: sha512-Cwo8LE/0rnvX7kIIa3QHCkcuF21c05Ayb0ZfxPiv0W8VRiZiNW/WuRupHKpqqGVGf7SUA44QSOUKaEd9lIrd/Q==} + dependencies: + '@types/mime': 1.3.2 + '@types/node': 18.16.14 + dev: true + + /@types/serve-static@1.15.1: + resolution: {integrity: sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ==} + dependencies: + '@types/mime': 3.0.1 + '@types/node': 18.16.14 + dev: true + + /@types/trusted-types@2.0.3: + resolution: {integrity: sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==} + dev: true + + /@types/unist@2.0.6: + resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} + dev: true + + /@types/web-bluetooth@0.0.14: + resolution: {integrity: sha512-5d2RhCard1nQUC3aHcq/gHzWYO6K0WJmAbjO7mQJgCQKtZpgXxv1rOM6O/dBDhDYYVutk1sciOgNSe+5YyfM8A==} + + /@types/web-bluetooth@0.0.17: + resolution: {integrity: sha512-4p9vcSmxAayx72yn70joFoL44c9MO/0+iVEBIQXe3v2h2SiAsEIo/G5v6ObFWvNKRFjbrVadNf9LqEEZeQPzdA==} + dev: false + + /@types/yargs-parser@21.0.0: + resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} + dev: true + + /@types/yargs@16.0.5: + resolution: {integrity: sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@types/yargs@17.0.24: + resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} + dependencies: + '@types/yargs-parser': 21.0.0 + dev: true + + /@typescript-eslint/eslint-plugin@5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-sXtOgJNEuRU5RLwPUb1jxtToZbgvq3M6FPpY4QENxoOggK+UpTxUBpj6tD8+Qh2g46Pi9We87E+eHnUw8YcGsw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@eslint-community/regexpp': 4.5.1 + '@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.59.6 + '@typescript-eslint/type-utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + debug: 4.3.4 + eslint: 8.41.0 + grapheme-splitter: 1.0.4 + ignore: 5.2.4 + natural-compare-lite: 1.4.0 + semver: 7.5.1 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/parser@5.59.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-7pCa6al03Pv1yf/dUg/s1pXz/yGMUBAw5EeWqNTFiSueKvRNonze3hma3lhdsOrQcaOXhbk5gKu2Fludiho9VA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/scope-manager': 5.59.6 + '@typescript-eslint/types': 5.59.6 + '@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5) + debug: 4.3.4 + eslint: 8.41.0 + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/scope-manager@5.59.6: + resolution: {integrity: sha512-gLbY3Le9Dxcb8KdpF0+SJr6EQ+hFGYFl6tVY8VxLPFDfUZC7BHFw+Vq7bM5lE9DwWPfx4vMWWTLGXgpc0mAYyQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.59.6 + '@typescript-eslint/visitor-keys': 5.59.6 + dev: true + + /@typescript-eslint/type-utils@5.59.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-A4tms2Mp5yNvLDlySF+kAThV9VTBPCvGf0Rp8nl/eoDX9Okun8byTKoj3fJ52IJitjWOk0fKPNQhXEB++eNozQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + debug: 4.3.4 + eslint: 8.41.0 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/types@5.59.6: + resolution: {integrity: sha512-tH5lBXZI7T2MOUgOWFdVNUILsI02shyQvfzG9EJkoONWugCG77NDDa1EeDGw7oJ5IvsTAAGVV8I3Tk2PNu9QfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /@typescript-eslint/typescript-estree@5.59.6(typescript@4.9.5): + resolution: {integrity: sha512-vW6JP3lMAs/Tq4KjdI/RiHaaJSO7IUsbkz17it/Rl9Q+WkQ77EOuOnlbaU8kKfVIOJxMhnRiBG+olE7f3M16DA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + dependencies: + '@typescript-eslint/types': 5.59.6 + '@typescript-eslint/visitor-keys': 5.59.6 + debug: 4.3.4 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.5.1 + tsutils: 3.21.0(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + dev: true + + /@typescript-eslint/utils@5.59.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-vzaaD6EXbTS29cVH0JjXBdzMt6VBlv+hE31XktDRMX1j3462wZCJa7VzO2AxXEXcIl8GQqZPcOPuW/Z1tZVogg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + '@types/json-schema': 7.0.11 + '@types/semver': 7.5.0 + '@typescript-eslint/scope-manager': 5.59.6 + '@typescript-eslint/types': 5.59.6 + '@typescript-eslint/typescript-estree': 5.59.6(typescript@4.9.5) + eslint: 8.41.0 + eslint-scope: 5.1.1 + semver: 7.5.1 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /@typescript-eslint/visitor-keys@5.59.6: + resolution: {integrity: sha512-zEfbFLzB9ETcEJ4HZEEsCR9HHeNku5/Qw1jSS5McYJv5BR+ftYXwFFAH5Al+xkGaZEqowMwl7uoJjQb1YSPF8Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + '@typescript-eslint/types': 5.59.6 + eslint-visitor-keys: 3.4.1 + dev: true + + /@unocss/astro@0.51.13(rollup@2.79.1)(vite@4.3.5): + resolution: {integrity: sha512-Dul0ZJNwseGBxngBMfghfTsf0quf4HcQcqJuIDzA1T+ueavpwf4QScwbDuS0BqFO4ZiIVSItA7f6eLe31PHUmw==} + dependencies: + '@unocss/core': 0.51.13 + '@unocss/reset': 0.51.13 + '@unocss/vite': 0.51.13(rollup@2.79.1)(vite@4.3.5) + transitivePeerDependencies: + - rollup + - vite + dev: true + + /@unocss/cli@0.51.13(rollup@2.79.1): + resolution: {integrity: sha512-g5CmSVyMFIgw/uStVlABldw+EYsrCyGjHd9jQMMTSZbV9IWuM0Tf+ILAZ+B4iXs62ctnrxPYH3Mha6IIuuZXZg==} + engines: {node: '>=14'} + hasBin: true + dependencies: + '@ampproject/remapping': 2.2.1 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@unocss/config': 0.51.13 + '@unocss/core': 0.51.13 + '@unocss/preset-uno': 0.51.13 + cac: 6.7.14 + chokidar: 3.5.3 + colorette: 2.0.20 + consola: 3.1.0 + fast-glob: 3.2.12 + magic-string: 0.30.0 + pathe: 1.1.0 + perfect-debounce: 1.0.0 + transitivePeerDependencies: + - rollup + dev: true + + /@unocss/config@0.51.13: + resolution: {integrity: sha512-EnSLt7Z1C01U3kORh+Iql+zLFm/PQTD1Np6oEW6U0/GTmD3HEilVFQFFxdM5F0X2bBZtZMkkAGGyhRWQj09hDQ==} + engines: {node: '>=14'} + dependencies: + '@unocss/core': 0.51.13 + unconfig: 0.3.7 + dev: true + + /@unocss/core@0.51.13: + resolution: {integrity: sha512-SclWkqY2c+p5+PiqrbQkhJNEExPdeo71/aGFye10tpBkgPJWd5xC7dhg5F8M4VPNBtuNCrvBWyqNnunMyuz/WQ==} + dev: true + + /@unocss/core@0.55.3: + resolution: {integrity: sha512-2hV9QlE/iOM4DHQ7i6L8sMC1t5/OVAz6AfGHjetTXcgbNfDCsHWqE8jhLZ1y2DeUvKwJvj2A09sYbYQ8E27+Gg==} + dev: true + + /@unocss/extractor-arbitrary-variants@0.51.13: + resolution: {integrity: sha512-lF7p0ea/MeNf4IsjzNhRNYP8u+f1h5JjhTzcvFpQo/vpBvuM5ZCyqp4mkXxYnLNLFfTLsc+MxXaU34IXxpw1QA==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/inspector@0.51.13: + resolution: {integrity: sha512-y6wCvLDmfFHfr5MHqcQLZkwRio4+VEH6j607bgUdKTRlZGVCD7/GBV8lperxsxpkspaE1eykOeDmW7Ms99SEuQ==} + dependencies: + gzip-size: 6.0.0 + sirv: 2.0.3 + dev: true + + /@unocss/postcss@0.51.13(postcss@8.4.23): + resolution: {integrity: sha512-V1QJ7md9jYtBwRc6NGep1Atc+QhaR3115B1wCo8CNM+v+ZOQzpxNsAshvOfyPzfzTj+KLtp4u4zqqaTbYGX2cw==} + engines: {node: '>=14'} + peerDependencies: + postcss: ^8.4.21 + dependencies: + '@unocss/config': 0.51.13 + '@unocss/core': 0.51.13 + css-tree: 2.3.1 + fast-glob: 3.2.12 + magic-string: 0.30.0 + postcss: 8.4.23 + dev: true + + /@unocss/preset-attributify@0.51.13: + resolution: {integrity: sha512-a501ylamV90E+tVf7Dgc8Plwex5LQ5oFSYwsxk06QhcxPWdLmDey3SQjL68AsP9qnLGfIez51sV4y/6H8wFqlw==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/preset-attributify@0.55.3: + resolution: {integrity: sha512-h3t6hPIk8pll3LubIIIsgRigvJivK3PX308Pi9Q0IUdw0vFq4S80iLQ1N0kRchQtgOaAIGffo9ux+TCbyunP3A==} + dependencies: + '@unocss/core': 0.55.3 + dev: true + + /@unocss/preset-icons@0.51.13: + resolution: {integrity: sha512-iL9s1NUVeWe3WSh5LHn7vy+veCAag9AFA50IfNlHuAARhuI8JtrMQA8dOXrWrzM0zWBMB+BVIkVaMVrF257n+Q==} + dependencies: + '@iconify/utils': 2.1.5 + '@unocss/core': 0.51.13 + ofetch: 1.0.1 + transitivePeerDependencies: + - supports-color + dev: true + + /@unocss/preset-mini@0.51.13: + resolution: {integrity: sha512-Wa6eMq8IiJEb7F8rL+cDX4XFm4ViAULaAvn8rjk7ANGdOmeqYGyGc0IZkOjQgl3PiFJFnitsBluHhg7nMIk7QQ==} + dependencies: + '@unocss/core': 0.51.13 + '@unocss/extractor-arbitrary-variants': 0.51.13 + dev: true + + /@unocss/preset-rem-to-px@0.51.13: + resolution: {integrity: sha512-bns33/AL+VUDN2lvIdV/rwhMZnMLg99pvpQP3plPPyOQgFjNlTqVvlza7jEa85OHfQH+/kZDlssHst0fdXAXXQ==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/preset-tagify@0.51.13: + resolution: {integrity: sha512-9pWPTff/1OKFmOQiGolVKFPzXwJ+r77UhXTB5E793uOQFHPMWCdkjyTPiN12FlB9izjTLIFH3GCGy/koRX9S4w==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/preset-typography@0.51.13: + resolution: {integrity: sha512-9uXrPztLsc8ZMnmoIdNAC3/gD183wyFECDzXtJqjOrJhzGr1kcv1sByyQO+kRPI67eWErSsDjpJwK2arfDOihQ==} + dependencies: + '@unocss/core': 0.51.13 + '@unocss/preset-mini': 0.51.13 + dev: true + + /@unocss/preset-uno@0.51.13: + resolution: {integrity: sha512-S9po93y87YphySfW21+Z5uzSL/GAGN5MqZURQxaGk9WGxYugAnu2PnvhhyqLCVmP05J34tMSDMkIZZqjnGaJzg==} + dependencies: + '@unocss/core': 0.51.13 + '@unocss/preset-mini': 0.51.13 + '@unocss/preset-wind': 0.51.13 + dev: true + + /@unocss/preset-web-fonts@0.51.13: + resolution: {integrity: sha512-jl6AhPcnLYN4oKYQZbU/40714IIuNb7TOFh2kgMkDH70r+fzLEdH+cB4l5m0yTsMhEQ6oDsppxm9aXcsVDRESA==} + dependencies: + '@unocss/core': 0.51.13 + ofetch: 1.0.1 + dev: true + + /@unocss/preset-wind@0.51.13: + resolution: {integrity: sha512-deRXLOWmKmqCJuohWCE5NUzs7XDJLn4pzgYQSUlEAVUfS6rzL49aJmSHA+p/f+HhJs5jipNdvkcrHYEBMNV1XQ==} + dependencies: + '@unocss/core': 0.51.13 + '@unocss/preset-mini': 0.51.13 + dev: true + + /@unocss/reset@0.51.13: + resolution: {integrity: sha512-xwYJW6vNbHIpBtlFcW93fZxILZpWatcCc9nclSgsl0YlFUz9w4/aoV9KqwU62Y4VUteJxCZCCXa3pSiPO8h5KA==} + dev: true + + /@unocss/scope@0.51.13: + resolution: {integrity: sha512-ATwgDx1qZflR2/EPsAs/XMR9/HdcUNyAZ6VdenwQQdlmAFlIWZQ6smswKyuiJWKtcJynfbdGOWcO3vcocrnSrQ==} + dev: true + + /@unocss/transformer-attributify-jsx-babel@0.51.13: + resolution: {integrity: sha512-HMEeTi3FIuI5gMJnRICbWdDmraL4NfpjSTjSmAo6EsraBuNO2m+/5JZL5Fc1B3olKes2G84FDSlzfofHyinWzw==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/transformer-attributify-jsx@0.51.13: + resolution: {integrity: sha512-vLAtT0K3Rfa3Xiu3LhU4tNCptuO3QlbgSsVO93K3onujfO7qZAaXjK5nj7jiLPyTKtQyl/3WOgNStfReMleF0w==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/transformer-compile-class@0.51.13: + resolution: {integrity: sha512-7G5ReCIkrZOAikwM9LN74nR4uxffJMSDAbLFDyhdh4qaumJFaxDLDQ4lxpQVZVeXQIF12QSxsnJuI9Fu1nuqmg==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/transformer-directives@0.51.13: + resolution: {integrity: sha512-1tl8UcVpqYaKkj1zan/QmUAslEcHe9WdN0/QX3Ao663A5r91EwWhnhwKFfvujrZp1XlFnXgKLmKS8OwTRQfCQg==} + dependencies: + '@unocss/core': 0.51.13 + css-tree: 2.3.1 + dev: true + + /@unocss/transformer-variant-group@0.51.13: + resolution: {integrity: sha512-QT3dfnYeht9SpqPFHJrEfZjL+XeMyi0Wwc4ll4ttIQNCl1Ihiwxl4ScRs1oVXlhCAc3hCXNu9V/FWO0cYHRt/Q==} + dependencies: + '@unocss/core': 0.51.13 + dev: true + + /@unocss/vite@0.51.13(rollup@2.79.1)(vite@4.3.5): + resolution: {integrity: sha512-WwyaPnu1XfRiFy4uxXwBuWaL7J1Rcaetsw5lJQUIUdSBTblsd6W7sW+MYTsLfAlA9FUxWDK4ESdI51Xgq4glxw==} + peerDependencies: + vite: ^2.9.0 || ^3.0.0-0 || ^4.0.0 + dependencies: + '@ampproject/remapping': 2.2.1 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@unocss/config': 0.51.13 + '@unocss/core': 0.51.13 + '@unocss/inspector': 0.51.13 + '@unocss/scope': 0.51.13 + '@unocss/transformer-directives': 0.51.13 + chokidar: 3.5.3 + fast-glob: 3.2.12 + magic-string: 0.30.0 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + transitivePeerDependencies: + - rollup + dev: true + + /@vitejs/plugin-vue@4.2.3(vite@4.3.5)(vue@3.3.4): + resolution: {integrity: sha512-R6JDUfiZbJA9cMiguQ7jxALsgiprjBeHL5ikpXfJCH62pPHtI+JdJ5xWj6Ev73yXSlYl86+blXn1kZHQ7uElxw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.0.0 + vue: ^3.2.25 + dependencies: + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + vue: 3.3.4 + dev: true + + /@vitest/expect@0.30.1: + resolution: {integrity: sha512-c3kbEtN8XXJSeN81iDGq29bUzSjQhjES2WR3aColsS4lPGbivwLtas4DNUe0jD9gg/FYGIteqOenfU95EFituw==} + dependencies: + '@vitest/spy': 0.30.1 + '@vitest/utils': 0.30.1 + chai: 4.3.7 + dev: true + + /@vitest/runner@0.30.1: + resolution: {integrity: sha512-W62kT/8i0TF1UBCNMRtRMOBWJKRnNyv9RrjIgdUryEe0wNpGZvvwPDLuzYdxvgSckzjp54DSpv1xUbv4BQ0qVA==} + dependencies: + '@vitest/utils': 0.30.1 + concordance: 5.0.4 + p-limit: 4.0.0 + pathe: 1.1.0 + dev: true + + /@vitest/snapshot@0.30.1: + resolution: {integrity: sha512-fJZqKrE99zo27uoZA/azgWyWbFvM1rw2APS05yB0JaLwUIg9aUtvvnBf4q7JWhEcAHmSwbrxKFgyBUga6tq9Tw==} + dependencies: + magic-string: 0.30.0 + pathe: 1.1.0 + pretty-format: 27.5.1 + dev: true + + /@vitest/spy@0.30.1: + resolution: {integrity: sha512-YfJeIf37GvTZe04ZKxzJfnNNuNSmTEGnla2OdL60C8od16f3zOfv9q9K0nNii0NfjDJRt/CVN/POuY5/zTS+BA==} + dependencies: + tinyspy: 2.1.0 + dev: true + + /@vitest/utils@0.30.1: + resolution: {integrity: sha512-/c8Xv2zUVc+rnNt84QF0Y0zkfxnaGhp87K2dYJMLtLOIckPzuxLVzAtFCicGFdB4NeBHNzTRr1tNn7rCtQcWFA==} + dependencies: + concordance: 5.0.4 + loupe: 2.3.6 + pretty-format: 27.5.1 + dev: true + + /@volar/language-core@1.4.1: + resolution: {integrity: sha512-EIY+Swv+TjsWpxOxujjMf1ZXqOjg9MT2VMXZ+1dKva0wD8W0L6EtptFFcCJdBbcKmGMFkr57Qzz9VNMWhs3jXQ==} + dependencies: + '@volar/source-map': 1.4.1 + dev: true + + /@volar/source-map@1.4.1: + resolution: {integrity: sha512-bZ46ad72dsbzuOWPUtJjBXkzSQzzSejuR3CT81+GvTEI2E994D8JPXzM3tl98zyCNnjgs4OkRyliImL1dvJ5BA==} + dependencies: + muggle-string: 0.2.2 + dev: true + + /@volar/typescript@1.4.1(typescript@4.9.5): + resolution: {integrity: sha512-phTy6p9yG6bgMIKQWEeDOi/aeT0njZsb1a/G1mrEuDsLmAn24Le4gDwSsGNhea6Uhu+3gdpUZn2PmZXa+WG2iQ==} + peerDependencies: + typescript: '*' + dependencies: + '@volar/language-core': 1.4.1 + typescript: 4.9.5 + dev: true + + /@volar/vue-language-core@1.6.4: + resolution: {integrity: sha512-1o+cAtN2DIDNAX/HS8rkjZc8wTMTK+zCab/qtYbvEVlmokhZiDrQeoD9/l0Ug7YCNg+mVuMNHKNBY7pX8U2/Jw==} + dependencies: + '@volar/language-core': 1.4.1 + '@volar/source-map': 1.4.1 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + minimatch: 9.0.1 + muggle-string: 0.2.2 + vue-template-compiler: 2.7.14 + dev: true + + /@volar/vue-typescript@1.6.4(typescript@4.9.5): + resolution: {integrity: sha512-qKwgP0KVQR/aaH/SN3AP7RB8NnXPWDn3tjyXP6IT6etxkDeZLBLsXWUD9KMak/RvV1DgbXDuz4F9yuZlbt29rA==} + peerDependencies: + typescript: '*' + dependencies: + '@volar/typescript': 1.4.1(typescript@4.9.5) + '@volar/vue-language-core': 1.6.4 + typescript: 4.9.5 + dev: true + + /@vue-macros/common@1.3.1(rollup@2.79.1)(vue@3.3.4): + resolution: {integrity: sha512-Lc5aP/8HNJD1XrnvpeNuWcCf82bZdR3auN/chA1b/1rKZgSnmQkH9f33tKO9qLwXSy+u4hpCi8Rw+oUuF1KCeg==} + engines: {node: '>=14.19.0'} + peerDependencies: + vue: ^2.7.0 || ^3.2.25 + peerDependenciesMeta: + vue: + optional: true + dependencies: + '@babel/types': 7.21.5 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@vue/compiler-sfc': 3.3.4 + local-pkg: 0.4.3 + magic-string-ast: 0.1.2 + vue: 3.3.4 + transitivePeerDependencies: + - rollup + dev: true + + /@vue/compiler-core@3.3.4: + resolution: {integrity: sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==} + dependencies: + '@babel/parser': 7.21.9 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + source-map-js: 1.0.2 + + /@vue/compiler-dom@3.3.4: + resolution: {integrity: sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==} + dependencies: + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + + /@vue/compiler-sfc@3.3.4: + resolution: {integrity: sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==} + dependencies: + '@babel/parser': 7.21.9 + '@vue/compiler-core': 3.3.4 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-ssr': 3.3.4 + '@vue/reactivity-transform': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.0 + postcss: 8.4.23 + source-map-js: 1.0.2 + + /@vue/compiler-ssr@3.3.4: + resolution: {integrity: sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/shared': 3.3.4 + + /@vue/devtools-api@6.5.0: + resolution: {integrity: sha512-o9KfBeaBmCKl10usN4crU53fYtC1r7jJwdGKjPT24t348rHxgfpZ0xL3Xm/gLUYnc0oTp8LAmrxOeLyu6tbk2Q==} + + /@vue/reactivity-transform@3.3.4: + resolution: {integrity: sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==} + dependencies: + '@babel/parser': 7.21.9 + '@vue/compiler-core': 3.3.4 + '@vue/shared': 3.3.4 + estree-walker: 2.0.2 + magic-string: 0.30.0 + + /@vue/reactivity@3.3.4: + resolution: {integrity: sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==} + dependencies: + '@vue/shared': 3.3.4 + + /@vue/runtime-core@3.3.4: + resolution: {integrity: sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==} + dependencies: + '@vue/reactivity': 3.3.4 + '@vue/shared': 3.3.4 + + /@vue/runtime-dom@3.3.4: + resolution: {integrity: sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==} + dependencies: + '@vue/runtime-core': 3.3.4 + '@vue/shared': 3.3.4 + csstype: 3.1.2 + + /@vue/server-renderer@3.3.4(vue@3.3.4): + resolution: {integrity: sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==} + peerDependencies: + vue: 3.3.4 + dependencies: + '@vue/compiler-ssr': 3.3.4 + '@vue/shared': 3.3.4 + vue: 3.3.4 + + /@vue/shared@3.3.4: + resolution: {integrity: sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==} + + /@vueuse/components@10.4.1(vue@3.3.4): + resolution: {integrity: sha512-hEWeumCfH394fkEYc/hng6T5VcjVkdqx7b75Sd6z4Uw3anjeo93Zp9qqtzFOv5bAmHls3Zy04Kowo1glrxDFRQ==} + dependencies: + '@vueuse/core': 10.4.1(vue@3.3.4) + '@vueuse/shared': 10.4.1(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/core@10.4.1(vue@3.3.4): + resolution: {integrity: sha512-DkHIfMIoSIBjMgRRvdIvxsyboRZQmImofLyOHADqiVbQVilP8VVHDhBX2ZqoItOgu7dWa8oXiNnScOdPLhdEXg==} + dependencies: + '@types/web-bluetooth': 0.0.17 + '@vueuse/metadata': 10.4.1 + '@vueuse/shared': 10.4.1(vue@3.3.4) + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/core@8.9.4(vue@3.3.4): + resolution: {integrity: sha512-B/Mdj9TK1peFyWaPof+Zf/mP9XuGAngaJZBwPaXBvU3aCTZlx3ltlrFFFyMV4iGBwsjSCeUCgZrtkEj9dS2Y3Q==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + '@types/web-bluetooth': 0.0.14 + '@vueuse/metadata': 8.9.4 + '@vueuse/shared': 8.9.4(vue@3.3.4) + vue: 3.3.4 + vue-demi: 0.14.5(vue@3.3.4) + + /@vueuse/metadata@10.4.1: + resolution: {integrity: sha512-2Sc8X+iVzeuMGHr6O2j4gv/zxvQGGOYETYXEc41h0iZXIRnRbJZGmY/QP8dvzqUelf8vg0p/yEA5VpCEu+WpZg==} + dev: false + + /@vueuse/metadata@8.9.4: + resolution: {integrity: sha512-IwSfzH80bnJMzqhaapqJl9JRIiyQU0zsRGEgnxN6jhq7992cPUJIRfV+JHRIZXjYqbwt07E1gTEp0R0zPJ1aqw==} + + /@vueuse/shared@10.4.1(vue@3.3.4): + resolution: {integrity: sha512-vz5hbAM4qA0lDKmcr2y3pPdU+2EVw/yzfRsBdu+6+USGa4PxqSQRYIUC9/NcT06y+ZgaTsyURw2I9qOFaaXHAg==} + dependencies: + vue-demi: 0.14.5(vue@3.3.4) + transitivePeerDependencies: + - '@vue/composition-api' + - vue + dev: false + + /@vueuse/shared@8.9.4(vue@3.3.4): + resolution: {integrity: sha512-wt+T30c4K6dGRMVqPddexEVLa28YwxW5OFIPmzUHICjphfAuBFTTdDoyqREZNDOFJZ44ARH1WWQNCUK8koJ+Ag==} + peerDependencies: + '@vue/composition-api': ^1.1.0 + vue: ^2.6.0 || ^3.2.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + vue: + optional: true + dependencies: + vue: 3.3.4 + vue-demi: 0.14.5(vue@3.3.4) + + /@yarnpkg/esbuild-plugin-pnp@3.0.0-rc.15(esbuild@0.17.19): + resolution: {integrity: sha512-kYzDJO5CA9sy+on/s2aIW0411AklfCi8Ck/4QDivOqsMKpStZA2SsR+X27VTggGwpStWaLrjJcDcdDMowtG8MA==} + engines: {node: '>=14.15.0'} + peerDependencies: + esbuild: '>=0.10.0' + dependencies: + esbuild: 0.17.19 + tslib: 2.5.2 + dev: true + + /accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + dev: true + + /acorn-jsx@5.3.2(acorn@7.4.1): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 7.4.1 + dev: true + + /acorn-jsx@5.3.2(acorn@8.8.2): + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + acorn: 8.8.2 + dev: true + + /acorn-walk@8.2.0: + resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + engines: {node: '>=0.4.0'} + dev: true + + /acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.10.0: + resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /acorn@8.8.2: + resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: true + + /address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + dev: true + + /agent-base@5.1.1: + resolution: {integrity: sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==} + engines: {node: '>= 6.0.0'} + dev: true + + /agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + dependencies: + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + dev: true + + /ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + dev: true + + /ajv@8.12.0: + resolution: {integrity: sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==} + dependencies: + fast-deep-equal: 3.1.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + uri-js: 4.4.1 + dev: true + + /ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + dependencies: + string-width: 4.2.3 + dev: true + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: true + + /ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + dependencies: + color-convert: 1.9.3 + dev: true + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + dev: true + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: true + + /app-root-dir@1.0.2: + resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==} + dev: true + + /aproba@2.0.0: + resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} + dev: true + + /are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + dev: true + + /argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + dependencies: + sprintf-js: 1.0.3 + dev: true + + /argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + dev: true + + /aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + dependencies: + deep-equal: 2.2.1 + dev: true + + /array-buffer-byte-length@1.0.0: + resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + dependencies: + call-bind: 1.0.2 + is-array-buffer: 3.0.2 + dev: true + + /array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + dev: true + + /array-includes@3.1.6: + resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + get-intrinsic: 1.2.1 + is-string: 1.0.7 + dev: true + + /array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + dev: true + + /array.prototype.flat@1.3.1: + resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + es-shim-unscopables: 1.0.0 + dev: true + + /array.prototype.flatmap@1.3.1: + resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + es-shim-unscopables: 1.0.0 + dev: true + + /asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + dev: true + + /assert-never@1.2.1: + resolution: {integrity: sha512-TaTivMB6pYI1kXwrFlEhLeGfOqoDNdTxjCdwRfFFkEA30Eu+k48W34nlok2EYWJfFFzqaEmichdNM7th6M5HNw==} + dev: true + + /assert@2.0.0: + resolution: {integrity: sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==} + dependencies: + es6-object-assign: 1.1.0 + is-nan: 1.3.2 + object-is: 1.1.5 + util: 0.12.5 + dev: true + + /assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + dev: true + + /ast-types@0.15.2: + resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.5.2 + dev: true + + /ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + dependencies: + tslib: 2.5.2 + dev: true + + /ast-walker-scope@0.4.1: + resolution: {integrity: sha512-Ro3nmapMxi/remlJdzFH0tiA7A59KDbxVoLlKWaLDrPELiftb9b8w+CCyWRM+sXZH5KHRAgv8feedW6mihvCHA==} + engines: {node: '>=14.19.0'} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + dev: true + + /async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + dev: true + + /async-validator@4.2.5: + resolution: {integrity: sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==} + dev: false + + /async@3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} + dev: true + + /asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + /at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true + + /available-typed-arrays@1.0.5: + resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + engines: {node: '>= 0.4'} + dev: true + + /axios@0.27.2: + resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==} + dependencies: + follow-redirects: 1.15.2 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + + /babel-core@7.0.0-bridge.0(@babel/core@7.21.8): + resolution: {integrity: sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + dev: true + + /babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + dependencies: + '@babel/helper-plugin-utils': 7.21.5 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.21.8): + resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/compat-data': 7.21.9 + '@babel/core': 7.21.8 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.8) + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.21.8): + resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.8) + core-js-compat: 3.30.2 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.21.8): + resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + dependencies: + '@babel/core': 7.21.8 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.21.8) + transitivePeerDependencies: + - supports-color + dev: true + + /babel-walk@3.0.0-canary-5: + resolution: {integrity: sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/types': 7.21.5 + dev: true + + /balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /better-opn@2.1.1: + resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==} + engines: {node: '>8.0.0'} + dependencies: + open: 7.4.2 + dev: true + + /big-integer@1.6.51: + resolution: {integrity: sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==} + engines: {node: '>=0.6'} + dev: true + + /binary-extensions@2.2.0: + resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} + engines: {node: '>=8'} + dev: true + + /bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /blueimp-md5@2.19.0: + resolution: {integrity: sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w==} + dev: true + + /body-parser@1.20.1: + resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.11.0 + raw-body: 2.5.1 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: true + + /boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + dev: true + + /bplist-parser@0.2.0: + resolution: {integrity: sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==} + engines: {node: '>= 5.10.0'} + dependencies: + big-integer: 1.6.51 + dev: true + + /brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + dependencies: + balanced-match: 1.0.2 + dev: true + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: true + + /browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + dev: true + + /browserify-zlib@0.1.4: + resolution: {integrity: sha512-19OEpq7vWgsH6WkvkBJQDFvJS1uPcbFOQ4v9CU839dO+ZZXUZO6XpE6hNCqvlIIj+4fZvRiJ6DsAQ382GwiyTQ==} + dependencies: + pako: 0.2.9 + dev: true + + /browserslist@4.21.5: + resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001489 + electron-to-chromium: 1.4.402 + node-releases: 2.0.11 + update-browserslist-db: 1.0.11(browserslist@4.21.5) + dev: true + + /bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + dependencies: + node-int64: 0.4.0 + dev: true + + /buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + dev: true + + /buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + dev: true + + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + + /builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + dev: true + + /builtins@5.0.1: + resolution: {integrity: sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==} + dependencies: + semver: 7.5.1 + dev: true + + /bytes@3.0.0: + resolution: {integrity: sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==} + engines: {node: '>= 0.8'} + dev: true + + /bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + dev: true + + /cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + dev: true + + /call-bind@1.0.2: + resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + dependencies: + function-bind: 1.1.1 + get-intrinsic: 1.2.1 + dev: true + + /callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + dev: true + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: true + + /camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + dev: true + + /caniuse-lite@1.0.30001489: + resolution: {integrity: sha512-x1mgZEXK8jHIfAxm+xgdpHpk50IN3z3q3zP261/WS+uvePxW8izXuCu6AHz0lkuYTlATDehiZ/tNyYBdSQsOUQ==} + dev: true + + /chai@4.3.7: + resolution: {integrity: sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A==} + engines: {node: '>=4'} + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.2 + deep-eql: 4.1.3 + get-func-name: 2.0.0 + loupe: 2.3.6 + pathval: 1.1.1 + type-detect: 4.0.8 + dev: true + + /chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + dev: true + + /chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + dev: true + + /character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + dev: true + + /character-parser@2.2.0: + resolution: {integrity: sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw==} + dependencies: + is-regex: 1.1.4 + dev: true + + /character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + dev: true + + /check-error@1.0.2: + resolution: {integrity: sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==} + dev: true + + /chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + dev: true + + /chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + dev: true + + /ci-info@3.8.0: + resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==} + engines: {node: '>=8'} + dev: true + + /clean-regexp@1.0.0: + resolution: {integrity: sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==} + engines: {node: '>=4'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + + /clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + dev: true + + /cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + dev: true + + /cli-table3@0.6.3: + resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} + engines: {node: 10.* || >= 12.*} + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + dev: true + + /clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + dev: true + + /color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + dependencies: + color-name: 1.1.3 + dev: true + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + dev: true + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + dev: true + + /colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + dev: true + + /combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + dependencies: + delayed-stream: 1.0.0 + + /commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + + /common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + + /commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + dev: true + + /compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + dev: true + + /compression@1.7.4: + resolution: {integrity: sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==} + engines: {node: '>= 0.8.0'} + dependencies: + accepts: 1.3.8 + bytes: 3.0.0 + compressible: 2.0.18 + debug: 2.6.9 + on-headers: 1.0.2 + safe-buffer: 5.1.2 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + dev: true + + /concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + dev: true + + /concordance@5.0.4: + resolution: {integrity: sha512-OAcsnTEYu1ARJqWVGwf4zh4JDfHZEaSNlNccFmt8YjB2l/n19/PF2viLINHc57vO4FKIAFl2FWASIGZZWZ2Kxw==} + engines: {node: '>=10.18.0 <11 || >=12.14.0 <13 || >=14'} + dependencies: + date-time: 3.1.0 + esutils: 2.0.3 + fast-diff: 1.3.0 + js-string-escape: 1.0.1 + lodash: 4.17.21 + md5-hex: 3.0.1 + semver: 7.5.1 + well-known-symbols: 2.0.0 + dev: true + + /consola@3.1.0: + resolution: {integrity: sha512-rrrJE6rP0qzl/Srg+C9x/AE5Kxfux7reVm1Wh0wCjuXvih6DqZgqDZe8auTD28fzJ9TF0mHlSDrPpWlujQRo1Q==} + dev: true + + /console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + dev: true + + /constantinople@4.0.1: + resolution: {integrity: sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw==} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + dev: true + + /content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + dev: true + + /convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + dev: true + + /cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + dev: true + + /cookie@0.5.0: + resolution: {integrity: sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==} + engines: {node: '>= 0.6'} + dev: true + + /core-js-compat@3.30.2: + resolution: {integrity: sha512-nriW1nuJjUgvkEjIot1Spwakz52V9YkYHZAQG6A1eCgC8AA1p0zngrQEP9R0+V6hji5XilWKG1Bd0YRppmGimA==} + dependencies: + browserslist: 4.21.5 + dev: true + + /core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: true + + /crypto-random-string@2.0.0: + resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==} + engines: {node: '>=8'} + dev: true + + /css-render@0.15.12: + resolution: {integrity: sha512-eWzS66patiGkTTik+ipO9qNGZ+uNuGyTmnz6/+EJIiFg8+3yZRpnMwgFo8YdXhQRsiePzehnusrxVvugNjXzbw==} + dependencies: + '@emotion/hash': 0.8.0 + csstype: 3.0.11 + dev: false + + /css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.0.2 + dev: true + + /cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /csstype@3.0.11: + resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} + dev: false + + /csstype@3.1.2: + resolution: {integrity: sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==} + + /date-fns-tz@1.3.8(date-fns@2.30.0): + resolution: {integrity: sha512-qwNXUFtMHTTU6CFSFjoJ80W8Fzzp24LntbjFFBgL/faqds4e5mo9mftoRLgr3Vi1trISsg4awSpYVsOQCRnapQ==} + peerDependencies: + date-fns: '>=2.0.0' + dependencies: + date-fns: 2.30.0 + dev: false + + /date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + dependencies: + '@babel/runtime': 7.21.5 + dev: false + + /date-time@3.1.0: + resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} + engines: {node: '>=6'} + dependencies: + time-zone: 1.0.0 + dev: true + + /de-indent@1.0.2: + resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} + dev: true + + /debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + dev: true + + /debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.2 + dev: true + + /deep-eql@4.1.3: + resolution: {integrity: sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==} + engines: {node: '>=6'} + dependencies: + type-detect: 4.0.8 + dev: true + + /deep-equal@2.2.1: + resolution: {integrity: sha512-lKdkdV6EOGoVn65XaOsPdH4rMxTZOnmFyuIkMjM1i5HHCbfjC97dawgTAy0deYNfuqUqW+Q5VrVaQYtUpSd6yQ==} + dependencies: + array-buffer-byte-length: 1.0.0 + call-bind: 1.0.2 + es-get-iterator: 1.1.3 + get-intrinsic: 1.2.1 + is-arguments: 1.1.1 + is-array-buffer: 3.0.2 + is-date-object: 1.0.5 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + isarray: 2.0.5 + object-is: 1.1.5 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + side-channel: 1.0.4 + which-boxed-primitive: 1.0.2 + which-collection: 1.0.1 + which-typed-array: 1.1.9 + dev: true + + /deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + dev: true + + /deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + dev: true + + /default-browser-id@3.0.0: + resolution: {integrity: sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==} + engines: {node: '>=12'} + dependencies: + bplist-parser: 0.2.0 + untildify: 4.0.0 + dev: true + + /define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + dev: true + + /define-properties@1.2.0: + resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + engines: {node: '>= 0.4'} + dependencies: + has-property-descriptors: 1.0.0 + object-keys: 1.1.1 + dev: true + + /defu@6.1.2: + resolution: {integrity: sha512-+uO4+qr7msjNNWKYPHqN/3+Dx3NFkmIzayk2L1MyZQlvgZb/J1A0fo410dpKrN2SnqFjt8n4JL8fDJE0wIgjFQ==} + dev: true + + /del@6.1.1: + resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} + engines: {node: '>=10'} + dependencies: + globby: 11.1.0 + graceful-fs: 4.2.11 + is-glob: 4.0.3 + is-path-cwd: 2.2.0 + is-path-inside: 3.0.3 + p-map: 4.0.0 + rimraf: 3.0.2 + slash: 3.0.0 + dev: true + + /delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + /delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + dev: true + + /depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dev: true + + /dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + dev: true + + /destr@1.2.2: + resolution: {integrity: sha512-lrbCJwD9saUQrqUfXvl6qoM+QN3W7tLV5pAOs+OqOmopCCz/JkE05MHedJR1xfk4IAnZuJXPVuN5+7jNA2ZCiA==} + dev: true + + /destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + dev: true + + /detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + dev: true + + /detect-package-manager@2.0.1: + resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: true + + /detect-port@1.5.1: + resolution: {integrity: sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ==} + hasBin: true + dependencies: + address: 1.2.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + dependencies: + path-type: 4.0.0 + dev: true + + /doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + dependencies: + esutils: 2.0.3 + dev: true + + /doctypes@1.1.0: + resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} + dev: true + + /dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + dev: true + + /dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + dev: true + + /domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: true + + /domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: true + + /domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: true + + /dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: true + + /dotenv@16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} + engines: {node: '>=12'} + dev: true + + /duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + dev: true + + /duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.1 + dev: true + + /ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + dev: true + + /ejs@3.1.9: + resolution: {integrity: sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + jake: 10.8.6 + dev: true + + /electron-to-chromium@1.4.402: + resolution: {integrity: sha512-gWYvJSkohOiBE6ecVYXkrDgNaUjo47QEKK0kQzmWyhkH+yoYiG44bwuicTGNSIQRG3WDMsWVZJLRnJnLNkbWvA==} + dev: true + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: true + + /encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + dev: true + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + + /entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + dev: true + + /envinfo@7.8.1: + resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + dependencies: + is-arrayish: 0.2.1 + dev: true + + /es-abstract@1.21.2: + resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.0 + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + es-set-tostringtag: 2.0.1 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.5 + get-intrinsic: 1.2.1 + get-symbol-description: 1.0.0 + globalthis: 1.0.3 + gopd: 1.0.1 + has: 1.0.3 + has-property-descriptors: 1.0.0 + has-proto: 1.0.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + is-array-buffer: 3.0.2 + is-callable: 1.2.7 + is-negative-zero: 2.0.2 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.2 + is-string: 1.0.7 + is-typed-array: 1.1.10 + is-weakref: 1.0.2 + object-inspect: 1.12.3 + object-keys: 1.1.1 + object.assign: 4.1.4 + regexp.prototype.flags: 1.5.0 + safe-regex-test: 1.0.0 + string.prototype.trim: 1.2.7 + string.prototype.trimend: 1.0.6 + string.prototype.trimstart: 1.0.6 + typed-array-length: 1.0.4 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.9 + dev: true + + /es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + is-arguments: 1.1.1 + is-map: 2.0.2 + is-set: 2.0.2 + is-string: 1.0.7 + isarray: 2.0.5 + stop-iteration-iterator: 1.0.0 + dev: true + + /es-module-lexer@0.9.3: + resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + dev: true + + /es-set-tostringtag@2.0.1: + resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + has-tostringtag: 1.0.0 + dev: true + + /es-shim-unscopables@1.0.0: + resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + dependencies: + has: 1.0.3 + dev: true + + /es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + dev: true + + /es6-object-assign@1.1.0: + resolution: {integrity: sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==} + dev: true + + /esbuild-plugin-alias@0.2.1: + resolution: {integrity: sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==} + dev: true + + /esbuild-register@3.4.2(esbuild@0.17.19): + resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} + peerDependencies: + esbuild: '>=0.12 <1' + dependencies: + debug: 4.3.4 + esbuild: 0.17.19 + transitivePeerDependencies: + - supports-color + dev: true + + /esbuild@0.17.19: + resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.17.19 + '@esbuild/android-arm64': 0.17.19 + '@esbuild/android-x64': 0.17.19 + '@esbuild/darwin-arm64': 0.17.19 + '@esbuild/darwin-x64': 0.17.19 + '@esbuild/freebsd-arm64': 0.17.19 + '@esbuild/freebsd-x64': 0.17.19 + '@esbuild/linux-arm': 0.17.19 + '@esbuild/linux-arm64': 0.17.19 + '@esbuild/linux-ia32': 0.17.19 + '@esbuild/linux-loong64': 0.17.19 + '@esbuild/linux-mips64el': 0.17.19 + '@esbuild/linux-ppc64': 0.17.19 + '@esbuild/linux-riscv64': 0.17.19 + '@esbuild/linux-s390x': 0.17.19 + '@esbuild/linux-x64': 0.17.19 + '@esbuild/netbsd-x64': 0.17.19 + '@esbuild/openbsd-x64': 0.17.19 + '@esbuild/sunos-x64': 0.17.19 + '@esbuild/win32-arm64': 0.17.19 + '@esbuild/win32-ia32': 0.17.19 + '@esbuild/win32-x64': 0.17.19 + dev: true + + /escalade@3.1.1: + resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} + engines: {node: '>=6'} + dev: true + + /escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + dev: true + + /escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + dev: true + + /escape-string-regexp@5.0.0: + resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==} + engines: {node: '>=12'} + dev: true + + /escodegen@2.0.0: + resolution: {integrity: sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==} + engines: {node: '>=6.0'} + hasBin: true + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.6.1 + dev: true + + /eslint-config-prettier@8.8.0(eslint@8.41.0): + resolution: {integrity: sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + dependencies: + eslint: 8.41.0 + dev: true + + /eslint-import-resolver-node@0.3.7: + resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} + dependencies: + debug: 3.2.7 + is-core-module: 2.12.1 + resolve: 1.22.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-module-utils@2.8.0(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint@8.41.0): + resolution: {integrity: sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + dependencies: + '@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + debug: 3.2.7 + eslint: 8.41.0 + eslint-import-resolver-node: 0.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-antfu@0.38.6(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-oQImiNKe+iGwoznuydq70s6oJHpaUE/hCHFeu4v7oy/hfAw7oBuCNi6TCZtQ/MUr+4XyQwq9sdC3fsLZC+DF1g==} + dependencies: + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + dev: true + + /eslint-plugin-es@4.1.0(eslint@8.41.0): + resolution: {integrity: sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==} + engines: {node: '>=8.10.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + eslint: 8.41.0 + eslint-utils: 2.1.0 + regexpp: 3.2.0 + dev: true + + /eslint-plugin-eslint-comments@3.2.0(eslint@8.41.0): + resolution: {integrity: sha512-0jkOl0hfojIHHmEHgmNdqv4fmh7300NdpA9FFpF7zaoLvB/QeXOGNLIo86oAveJFrfB1p05kC8hpEMHM8DwWVQ==} + engines: {node: '>=6.5.0'} + peerDependencies: + eslint: '>=4.19.1' + dependencies: + escape-string-regexp: 1.0.5 + eslint: 8.41.0 + ignore: 5.2.4 + dev: true + + /eslint-plugin-html@7.1.0: + resolution: {integrity: sha512-fNLRraV/e6j8e3XYOC9xgND4j+U7b1Rq+OygMlLcMg+wI/IpVbF+ubQa3R78EjKB9njT6TQOlcK5rFKBVVtdfg==} + dependencies: + htmlparser2: 8.0.2 + dev: true + + /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.59.6)(eslint@8.41.0): + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + dependencies: + '@typescript-eslint/parser': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + array-includes: 3.1.6 + array.prototype.flat: 1.3.1 + array.prototype.flatmap: 1.3.1 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.41.0 + eslint-import-resolver-node: 0.3.7 + eslint-module-utils: 2.8.0(@typescript-eslint/parser@5.59.6)(eslint-import-resolver-node@0.3.7)(eslint@8.41.0) + has: 1.0.3 + is-core-module: 2.12.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.1.6 + resolve: 1.22.2 + semver: 6.3.0 + tsconfig-paths: 3.14.2 + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + dev: true + + /eslint-plugin-jest@27.2.1(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-l067Uxx7ZT8cO9NJuf+eJHvt6bqJyz2Z29wykyEdz/OtmcELQl2MQGQLX8J94O1cSJWAwUSEvCjwjA7KEK3Hmg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-jsonc@2.8.0(eslint@8.41.0): + resolution: {integrity: sha512-K4VsnztnNwpm+V49CcCu5laq8VjclJpuhfI9LFkOrOyK+BKdQHMzkWo43B4X4rYaVrChm4U9kw/tTU5RHh5Wtg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + eslint: 8.41.0 + jsonc-eslint-parser: 2.3.0 + natural-compare: 1.4.0 + dev: true + + /eslint-plugin-markdown@3.0.0(eslint@8.41.0): + resolution: {integrity: sha512-hRs5RUJGbeHDLfS7ELanT0e29Ocyssf/7kBM+p7KluY5AwngGkDf8Oyu4658/NZSGTTq05FZeWbkxXtbVyHPwg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.41.0 + mdast-util-from-markdown: 0.8.5 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-n@15.7.0(eslint@8.41.0): + resolution: {integrity: sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==} + engines: {node: '>=12.22.0'} + peerDependencies: + eslint: '>=7.0.0' + dependencies: + builtins: 5.0.1 + eslint: 8.41.0 + eslint-plugin-es: 4.1.0(eslint@8.41.0) + eslint-utils: 3.0.0(eslint@8.41.0) + ignore: 5.2.4 + is-core-module: 2.12.1 + minimatch: 3.1.2 + resolve: 1.22.2 + semver: 7.5.1 + dev: true + + /eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + dev: true + + /eslint-plugin-promise@6.1.1(eslint@8.41.0): + resolution: {integrity: sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + dependencies: + eslint: 8.41.0 + dev: true + + /eslint-plugin-storybook@0.6.12(eslint@8.41.0)(typescript@4.9.5): + resolution: {integrity: sha512-XbIvrq6hNVG6rpdBr+eBw63QhOMLpZneQVSooEDow8aQCWGCk/5vqtap1yxpVydNfSxi3S/3mBBRLQqKUqQRww==} + engines: {node: 12.x || 14.x || >= 16} + peerDependencies: + eslint: '>=6' + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/utils': 5.59.6(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + requireindex: 1.2.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + - typescript + dev: true + + /eslint-plugin-unicorn@46.0.1(eslint@8.41.0): + resolution: {integrity: sha512-setGhMTiLAddg1asdwjZ3hekIN5zLznNa5zll7pBPwFOka6greCKDQydfqy4fqyUhndi74wpDzClSQMEcmOaew==} + engines: {node: '>=14.18'} + peerDependencies: + eslint: '>=8.28.0' + dependencies: + '@babel/helper-validator-identifier': 7.19.1 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + ci-info: 3.8.0 + clean-regexp: 1.0.0 + eslint: 8.41.0 + esquery: 1.5.0 + indent-string: 4.0.0 + is-builtin-module: 3.2.1 + jsesc: 3.0.2 + lodash: 4.17.21 + pluralize: 8.0.0 + read-pkg-up: 7.0.1 + regexp-tree: 0.1.27 + regjsparser: 0.9.1 + safe-regex: 2.1.1 + semver: 7.5.1 + strip-indent: 3.0.0 + dev: true + + /eslint-plugin-unused-imports@2.0.0(@typescript-eslint/eslint-plugin@5.59.6)(eslint@8.41.0): + resolution: {integrity: sha512-3APeS/tQlTrFa167ThtP0Zm0vctjr4M44HMpeg1P4bK6wItarumq0Ma82xorMKdFsWpphQBlRPzw/pxiVELX1A==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^8.0.0 + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + dependencies: + '@typescript-eslint/eslint-plugin': 5.59.6(@typescript-eslint/parser@5.59.6)(eslint@8.41.0)(typescript@4.9.5) + eslint: 8.41.0 + eslint-rule-composer: 0.3.0 + dev: true + + /eslint-plugin-vue@9.13.0(eslint@8.41.0): + resolution: {integrity: sha512-aBz9A8WB4wmpnVv0pYUt86cmH9EkcwWzgEwecBxMoRNhQjTL5i4sqadnwShv/hOdr8Hbl8XANGV7dtX9UQIAyA==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + eslint: 8.41.0 + natural-compare: 1.4.0 + nth-check: 2.1.1 + postcss-selector-parser: 6.0.13 + semver: 7.5.1 + vue-eslint-parser: 9.3.0(eslint@8.41.0) + xml-name-validator: 4.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-plugin-yml@1.7.0(eslint@8.41.0): + resolution: {integrity: sha512-qq61FQJk+qIgWl0R06bec7UQQEIBrUH22jS+MroTbFUKu+3/iVlGRpZd8mjpOAm/+H/WEDFwy4x/+kKgVGbsWw==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.41.0 + lodash: 4.17.21 + natural-compare: 1.4.0 + yaml-eslint-parser: 1.2.2 + transitivePeerDependencies: + - supports-color + dev: true + + /eslint-rule-composer@0.3.0: + resolution: {integrity: sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==} + engines: {node: '>=4.0.0'} + dev: true + + /eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + dev: true + + /eslint-scope@7.2.0: + resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + dev: true + + /eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + dependencies: + eslint-visitor-keys: 1.3.0 + dev: true + + /eslint-utils@3.0.0(eslint@8.41.0): + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + dependencies: + eslint: 8.41.0 + eslint-visitor-keys: 2.1.0 + dev: true + + /eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + dev: true + + /eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + dev: true + + /eslint-visitor-keys@3.4.1: + resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dev: true + + /eslint@8.41.0: + resolution: {integrity: sha512-WQDQpzGBOP5IrXPo4Hc0814r4/v2rrIsB0rhT7jtunIalgg6gYXWhRMOejVO8yH21T/FGaxjmFjBMNqcIlmH1Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + hasBin: true + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.41.0) + '@eslint-community/regexpp': 4.5.1 + '@eslint/eslintrc': 2.0.3 + '@eslint/js': 8.41.0 + '@humanwhocodes/config-array': 0.11.8 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.4 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.0 + eslint-visitor-keys: 3.4.1 + espree: 9.5.2 + esquery: 1.5.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.20.0 + graphemer: 1.4.0 + ignore: 5.2.4 + import-fresh: 3.3.0 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + 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 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + dev: true + + /espree@6.2.1: + resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} + engines: {node: '>=6.0.0'} + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + dev: true + + /espree@9.5.2: + resolution: {integrity: sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.2 + acorn-jsx: 5.3.2(acorn@8.8.2) + eslint-visitor-keys: 3.4.1 + dev: true + + /esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /esquery@1.5.0: + resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} + engines: {node: '>=0.10'} + dependencies: + estraverse: 5.3.0 + dev: true + + /esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + dependencies: + estraverse: 5.3.0 + dev: true + + /estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + dev: true + + /estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + dev: true + + /estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + dev: true + + /estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + /esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + dev: true + + /evtd@0.2.4: + resolution: {integrity: sha512-qaeGN5bx63s/AXgQo8gj6fBkxge+OoLddLniox5qtLAEY5HSnuSlISXVPxnSae1dWblvTh4/HoMIB+mbMsvZzw==} + dev: false + + /execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + + /express@4.18.2: + resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + engines: {node: '>= 0.10.0'} + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.1 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.5.0 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.2.0 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.1 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.7 + proxy-addr: 2.0.7 + qs: 6.11.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.18.0 + serve-static: 1.15.0 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + dev: true + + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + + /extract-zip@1.7.0: + resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true + dependencies: + concat-stream: 1.6.2 + debug: 2.6.9 + mkdirp: 0.5.6 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + dev: true + + /fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + dev: true + + /fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + dev: true + + /fast-glob@3.2.12: + resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} + engines: {node: '>=8.6.0'} + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.5 + dev: true + + /fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + dev: true + + /fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + dev: true + + /fastq@1.15.0: + resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==} + dependencies: + reusify: 1.0.4 + dev: true + + /fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + dependencies: + bser: 2.1.1 + dev: true + + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: true + + /fetch-retry@5.0.6: + resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} + dev: true + + /file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flat-cache: 3.0.4 + dev: true + + /file-system-cache@2.3.0: + resolution: {integrity: sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ==} + dependencies: + fs-extra: 11.1.1 + ramda: 0.29.0 + dev: true + + /filelist@1.0.4: + resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + dependencies: + minimatch: 5.1.6 + dev: true + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: true + + /finalhandler@1.2.0: + resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} + engines: {node: '>= 0.8'} + 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 + transitivePeerDependencies: + - supports-color + dev: true + + /find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + dev: true + + /find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + dev: true + + /find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + dependencies: + locate-path: 3.0.0 + dev: true + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: true + + /find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + dev: true + + /flat-cache@3.0.4: + resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} + engines: {node: ^10.12.0 || >=12.0.0} + dependencies: + flatted: 3.2.7 + rimraf: 3.0.2 + dev: true + + /flatted@3.2.7: + resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} + dev: true + + /flow-parser@0.206.0: + resolution: {integrity: sha512-HVzoK3r6Vsg+lKvlIZzaWNBVai+FXTX1wdYhz/wVlH13tb/gOdLXmlTqy6odmTBhT5UoWUbq0k8263Qhr9d88w==} + engines: {node: '>=0.4.0'} + dev: true + + /follow-redirects@1.15.2: + resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: true + + /form-data@3.0.1: + resolution: {integrity: sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + + /form-data@4.0.0: + resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} + engines: {node: '>= 6'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: false + + /forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + dev: true + + /fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + dev: true + + /fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + dev: true + + /fs-extra@11.1.1: + resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + engines: {node: '>=14.14'} + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.0 + dev: true + + /fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + dev: true + + /fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents@2.3.2: + resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /function-bind@1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /function.prototype.name@1.1.5: + resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + functions-have-names: 1.2.3 + dev: true + + /functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + dev: true + + /gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + dependencies: + aproba: 2.0.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + dev: true + + /gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + dev: true + + /get-func-name@2.0.0: + resolution: {integrity: sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==} + dev: true + + /get-intrinsic@1.2.1: + resolution: {integrity: sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==} + dependencies: + function-bind: 1.1.1 + has: 1.0.3 + has-proto: 1.0.1 + has-symbols: 1.0.3 + dev: true + + /get-npm-tarball-url@2.0.3: + resolution: {integrity: sha512-R/PW6RqyaBQNWYaSyfrh54/qtcnOp22FHCCiRhSSZj0FP3KQWCsxxt0DzIdVTbwTqe9CtQfvl/FPD4UIPt4pqw==} + engines: {node: '>=12.17'} + dev: true + + /get-own-enumerable-property-symbols@3.0.2: + resolution: {integrity: sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g==} + dev: true + + /get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + dev: true + + /get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + dev: true + + /get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + dev: true + + /get-symbol-description@1.0.0: + resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + + /giget@1.1.2: + resolution: {integrity: sha512-HsLoS07HiQ5oqvObOI+Qb2tyZH4Gj5nYGfF9qQcZNrPw+uEFhdXtgJr01aO2pWadGHucajYDLxxbtQkm97ON2A==} + hasBin: true + dependencies: + colorette: 2.0.20 + defu: 6.1.2 + https-proxy-agent: 5.0.1 + mri: 1.2.0 + node-fetch-native: 1.1.1 + pathe: 1.1.0 + tar: 6.1.15 + transitivePeerDependencies: + - supports-color + dev: true + + /github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + dev: true + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + dependencies: + is-glob: 4.0.3 + dev: true + + /glob-promise@6.0.2(glob@8.1.0): + resolution: {integrity: sha512-Ni2aDyD1ekD6x8/+K4hDriRDbzzfuK4yKpqSymJ4P7IxbtARiOOuU+k40kbHM0sLIlbf1Qh0qdMkAHMZYE6XJQ==} + engines: {node: '>=16'} + peerDependencies: + glob: ^8.0.3 + dependencies: + '@types/glob': 8.1.0 + glob: 8.1.0 + dev: true + + /glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + dev: true + + /glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + dev: true + + /globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + dev: true + + /globals@13.20.0: + resolution: {integrity: sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==} + engines: {node: '>=8'} + dependencies: + type-fest: 0.20.2 + dev: true + + /globalthis@1.0.3: + resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} + engines: {node: '>= 0.4'} + dependencies: + define-properties: 1.2.0 + dev: true + + /globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.4 + merge2: 1.4.1 + slash: 3.0.0 + dev: true + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + dev: true + + /grapheme-splitter@1.0.4: + resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} + dev: true + + /graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + dev: true + + /gunzip-maybe@1.4.2: + resolution: {integrity: sha512-4haO1M4mLO91PW57BMsDFf75UmwoRX0GkdD+Faw+Lr+r/OZrOCS0pIBwOL1xCKQqnQzbNFGgK2V2CpBUPeFNTw==} + hasBin: true + dependencies: + browserify-zlib: 0.1.4 + is-deflate: 1.0.0 + is-gzip: 1.0.0 + peek-stream: 1.1.3 + pumpify: 1.5.1 + through2: 2.0.5 + dev: true + + /gzip-size@6.0.0: + resolution: {integrity: sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==} + engines: {node: '>=10'} + dependencies: + duplexer: 0.1.2 + dev: true + + /handlebars@4.7.7: + resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} + engines: {node: '>=0.4.7'} + hasBin: true + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.17.4 + dev: true + + /has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + dev: true + + /has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + dev: true + + /has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-property-descriptors@1.0.0: + resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + dependencies: + get-intrinsic: 1.2.1 + dev: true + + /has-proto@1.0.1: + resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + engines: {node: '>= 0.4'} + dev: true + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: true + + /has-tostringtag@1.0.0: + resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + dev: true + + /has@1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /hash-sum@2.0.0: + resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==} + dev: true + + /he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + dev: true + + /highlight.js@11.8.0: + resolution: {integrity: sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==} + engines: {node: '>=12.0.0'} + dev: false + + /hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + dev: true + + /htmlparser2@8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + dev: true + + /http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + dev: true + + /https-proxy-agent@4.0.0: + resolution: {integrity: sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==} + engines: {node: '>= 6.0.0'} + dependencies: + agent-base: 5.1.1 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + dependencies: + agent-base: 6.0.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + dev: true + + /human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + dev: true + + /husky@8.0.3: + resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} + engines: {node: '>=14'} + hasBin: true + dev: true + + /iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /idb@7.1.1: + resolution: {integrity: sha512-gchesWBzyvGHRO9W8tzUWFDycow5gwjvFKfyV9FF32Y7F50yZMp7mP+T2mJIWFx49zicqyC4uefHM17o6xKIVQ==} + dev: true + + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + + /ignore@5.2.4: + resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} + engines: {node: '>= 4'} + dev: true + + /immutable@4.3.0: + resolution: {integrity: sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg==} + dev: true + + /import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + dev: true + + /imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + dev: true + + /indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + dev: true + + /inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /internal-slot@1.0.5: + resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.1 + has: 1.0.3 + side-channel: 1.0.4 + dev: true + + /interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + dev: true + + /ip@2.0.0: + resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} + dev: true + + /ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + dev: true + + /is-absolute-url@3.0.3: + resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==} + engines: {node: '>=8'} + dev: true + + /is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + dev: true + + /is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + dev: true + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-array-buffer@3.0.2: + resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-typed-array: 1.1.10 + dev: true + + /is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + dev: true + + /is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + dependencies: + has-bigints: 1.0.2 + dev: true + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.2.0 + dev: true + + /is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + dependencies: + builtin-modules: 3.3.0 + dev: true + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: true + + /is-core-module@2.12.1: + resolution: {integrity: sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==} + dependencies: + has: 1.0.3 + dev: true + + /is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + dev: true + + /is-deflate@1.0.0: + resolution: {integrity: sha512-YDoFpuZWu1VRXlsnlYMzKyVRITXj7Ej/V9gXQ2/pAe7X1J7M/RNOqaIYi6qUn+B7nGyB9pDXrv02dsB58d2ZAQ==} + dev: true + + /is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + dev: true + + /is-expression@4.0.0: + resolution: {integrity: sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A==} + dependencies: + acorn: 7.4.1 + object-assign: 4.1.1 + dev: true + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: true + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: true + + /is-gzip@1.0.0: + resolution: {integrity: sha512-rcfALRIb1YewtnksfRIHGcIY93QnK8BIQ/2c9yDYcG/Y6+vRoJuTWBmmSEbyLLYtXm7q35pHOHbZFQBaLrhlWQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + dev: true + + /is-map@2.0.2: + resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} + dev: true + + /is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + dev: true + + /is-nan@1.3.2: + resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + dev: true + + /is-negative-zero@2.0.2: + resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + engines: {node: '>= 0.4'} + dev: true + + /is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: true + + /is-obj@1.0.1: + resolution: {integrity: sha512-l4RyHgRqGN4Y3+9JHVrNqO+tN0rV5My76uW5/nuO4K1b6vw5G8d/cmFjP9tRfEsdhZNt0IFdZuK/c2Vr4Nb+Qg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + dev: true + + /is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + dev: true + + /is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + dev: true + + /is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + has-tostringtag: 1.0.0 + dev: true + + /is-regexp@1.0.0: + resolution: {integrity: sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==} + engines: {node: '>=0.10.0'} + dev: true + + /is-set@2.0.2: + resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} + dev: true + + /is-shared-array-buffer@1.0.2: + resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + dev: true + + /is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.0 + dev: true + + /is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: true + + /is-typed-array@1.1.10: + resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + dev: true + + /is-weakmap@2.0.1: + resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} + dev: true + + /is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + dependencies: + call-bind: 1.0.2 + dev: true + + /is-weakset@2.0.2: + resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + dev: true + + /is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + dev: true + + /isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + dev: true + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: true + + /isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + dependencies: + node-fetch: 2.6.11 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + dev: true + + /istanbul-lib-coverage@3.2.0: + resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + engines: {node: '>=8'} + dev: true + + /istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + dependencies: + '@babel/core': 7.21.8 + '@babel/parser': 7.21.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.0 + semver: 6.3.0 + transitivePeerDependencies: + - supports-color + dev: true + + /jake@10.8.6: + resolution: {integrity: sha512-G43Ub9IYEFfu72sua6rzooi8V8Gz2lkfk48rW20vEWCGizeaEPlKB1Kh8JIA84yQbiAEfqlPmSpGgCKKxH3rDA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + async: 3.2.4 + chalk: 4.1.2 + filelist: 1.0.4 + minimatch: 3.1.2 + dev: true + + /jest-haste-map@29.5.0: + resolution: {integrity: sha512-IspOPnnBro8YfVYSw6yDRKh/TiCdRngjxeacCps1cQ9cgVN6+10JUcuJ1EabrgYLOATsIAigxA0rLR9x/YlrSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.5.0 + '@types/graceful-fs': 4.1.6 + '@types/node': 18.16.14 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.4.3 + jest-util: 29.5.0 + jest-worker: 29.5.0 + micromatch: 4.0.5 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /jest-mock@27.5.1: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + '@jest/types': 27.5.1 + '@types/node': 18.16.14 + dev: true + + /jest-regex-util@29.4.3: + resolution: {integrity: sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dev: true + + /jest-util@29.5.0: + resolution: {integrity: sha512-RYMgG/MTadOr5t8KdhejfvUU82MxsCu5MF6KuDUHl+NuwzUt+Sm6jJWxTJVrDR1j5M/gJVCPKQEpWXY+yIQ6lQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@jest/types': 29.5.0 + '@types/node': 18.16.14 + chalk: 4.1.2 + ci-info: 3.8.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + dev: true + + /jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + dependencies: + '@types/node': 18.16.14 + merge-stream: 2.0.0 + supports-color: 7.2.0 + dev: true + + /jest-worker@29.5.0: + resolution: {integrity: sha512-NcrQnevGoSp4b5kg+akIpthoAFHxPBcb5P6mYPY0fUNT+sSvmtu6jlkEle3anczUKIKEbMxFimk9oTP/tpIPgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@types/node': 18.16.14 + jest-util: 29.5.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + dev: true + + /jiti@1.18.2: + resolution: {integrity: sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==} + hasBin: true + dev: true + + /js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + dev: true + + /js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + dev: true + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + dev: true + + /js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + dependencies: + argparse: 2.0.1 + dev: true + + /jscodeshift@0.14.0(@babel/preset-env@7.21.5): + resolution: {integrity: sha512-7eCC1knD7bLUPuSCwXsMZUH51O8jIcoVyKtI6P0XM0IVzlGjckPy3FIwQlorzbN0Sg79oK+RlohN32Mqf/lrYA==} + hasBin: true + peerDependencies: + '@babel/preset-env': ^7.1.6 + dependencies: + '@babel/core': 7.21.8 + '@babel/parser': 7.21.9 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.21.8) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.21.8) + '@babel/plugin-transform-modules-commonjs': 7.21.5(@babel/core@7.21.8) + '@babel/preset-env': 7.21.5(@babel/core@7.21.8) + '@babel/preset-flow': 7.21.4(@babel/core@7.21.8) + '@babel/preset-typescript': 7.21.5(@babel/core@7.21.8) + '@babel/register': 7.21.0(@babel/core@7.21.8) + babel-core: 7.0.0-bridge.0(@babel/core@7.21.8) + chalk: 4.1.2 + flow-parser: 0.206.0 + graceful-fs: 4.2.11 + micromatch: 4.0.5 + neo-async: 2.6.2 + node-dir: 0.1.17 + recast: 0.21.5 + temp: 0.8.4 + write-file-atomic: 2.4.3 + transitivePeerDependencies: + - supports-color + dev: true + + /jsesc@0.5.0: + resolution: {integrity: sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==} + hasBin: true + dev: true + + /jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + dev: true + + /json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + dev: true + + /json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + dev: true + + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + dev: true + + /json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + dev: true + + /jsonc-eslint-parser@1.4.1: + resolution: {integrity: sha512-hXBrvsR1rdjmB2kQmUjf1rEIa+TqHBGMge8pwi++C+Si1ad7EjZrJcpgwym+QGK/pqTx+K7keFAtLlVNdLRJOg==} + engines: {node: '>=8.10.0'} + dependencies: + acorn: 7.4.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 1.3.0 + espree: 6.2.1 + semver: 6.3.0 + dev: true + + /jsonc-eslint-parser@2.3.0: + resolution: {integrity: sha512-9xZPKVYp9DxnM3sd1yAsh/d59iIaswDkai8oTxbursfKYbg/ibjX0IzFt35+VZ8iEW453TVTXztnRvYUQlAfUQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + dependencies: + acorn: 8.8.2 + eslint-visitor-keys: 3.4.1 + espree: 9.5.2 + semver: 7.5.1 + dev: true + + /jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + dev: true + + /jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + dependencies: + universalify: 2.0.0 + optionalDependencies: + graceful-fs: 4.2.11 + dev: true + + /jsonpointer@5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + dev: true + + /jstransformer@1.0.0: + resolution: {integrity: sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A==} + dependencies: + is-promise: 2.2.2 + promise: 7.3.1 + dev: true + + /kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + dev: true + + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: true + + /lazy-universal-dotenv@4.0.0: + resolution: {integrity: sha512-aXpZJRnTkpK6gQ/z4nk+ZBLd/Qdp118cvPruLSIQzQNRhKwEcdXCOzXuF55VDqIiuAaY3UGZ10DJtvZzDcvsxg==} + engines: {node: '>=14.0.0'} + dependencies: + app-root-dir: 1.0.2 + dotenv: 16.0.3 + dotenv-expand: 10.0.0 + dev: true + + /leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + dev: true + + /levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + dev: true + + /levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + dev: true + + /lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + dev: true + + /local-pkg@0.4.3: + resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + engines: {node: '>=14'} + dev: true + + /locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + dev: true + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: true + + /locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + dependencies: + p-locate: 5.0.0 + dev: true + + /lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + dev: false + + /lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + dev: true + + /lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + dev: true + + /lodash.sortby@4.7.0: + resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + dev: true + + /lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /loupe@2.3.6: + resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + dependencies: + get-func-name: 2.0.0 + dev: true + + /lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + dependencies: + yallist: 3.1.1 + dev: true + + /lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + dependencies: + yallist: 4.0.0 + dev: true + + /lru-cache@8.0.5: + resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} + engines: {node: '>=16.14'} + dev: true + + /lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + dev: true + + /magic-string-ast@0.1.2: + resolution: {integrity: sha512-P53AZrzq7hclCU6HWj88xNZHmP15DKjMmK/vBytO1qnpYP3ul4IEZlyCE0aU3JRnmgWmZPmoTKj4Bls7v0pMyA==} + engines: {node: '>=14.19.0'} + dependencies: + magic-string: 0.30.0 + dev: true + + /magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string@0.26.7: + resolution: {integrity: sha512-hX9XH3ziStPoPhJxLq1syWuZMxbDvGNbVchfrdCtanC7D13888bMFow61x8axrx+GfHLtVeAx2kxL7tTGRl+Ow==} + engines: {node: '>=12'} + dependencies: + sourcemap-codec: 1.4.8 + dev: true + + /magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + dev: true + + /magic-string@0.30.0: + resolution: {integrity: sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==} + engines: {node: '>=12'} + dependencies: + '@jridgewell/sourcemap-codec': 1.4.15 + + /make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + dependencies: + pify: 4.0.1 + semver: 5.7.1 + dev: true + + /make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + dependencies: + semver: 6.3.0 + dev: true + + /makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + dependencies: + tmpl: 1.0.5 + dev: true + + /map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + dev: true + + /markdown-to-jsx@7.2.0(react@18.2.0): + resolution: {integrity: sha512-3l4/Bigjm4bEqjCR6Xr+d4DtM1X6vvtGsMGSjJYyep8RjjIvcWtrXBS8Wbfe1/P+atKNMccpsraESIaWVplzVg==} + engines: {node: '>= 10'} + peerDependencies: + react: '>= 0.14.0' + dependencies: + react: 18.2.0 + dev: true + + /md5-hex@3.0.1: + resolution: {integrity: sha512-BUiRtTtV39LIJwinWBjqVsU9xhdnz7/i889V859IBFpuqGAj6LuOvHv5XLbgZ2R7ptJoJaEcxkv88/h25T7Ciw==} + engines: {node: '>=8'} + dependencies: + blueimp-md5: 2.19.0 + dev: true + + /mdast-util-definitions@4.0.0: + resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} + dependencies: + unist-util-visit: 2.0.3 + dev: true + + /mdast-util-from-markdown@0.8.5: + resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} + dependencies: + '@types/mdast': 3.0.11 + mdast-util-to-string: 2.0.0 + micromark: 2.11.4 + parse-entities: 2.0.0 + unist-util-stringify-position: 2.0.3 + transitivePeerDependencies: + - supports-color + dev: true + + /mdast-util-to-string@1.1.0: + resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} + dev: true + + /mdast-util-to-string@2.0.0: + resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} + dev: true + + /mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + dev: true + + /media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + dev: true + + /memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + dependencies: + map-or-similar: 1.5.0 + dev: true + + /merge-descriptors@1.0.1: + resolution: {integrity: sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==} + dev: true + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + + /merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + dev: true + + /methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + dev: true + + /micromark@2.11.4: + resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} + dependencies: + debug: 4.3.4 + parse-entities: 2.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: true + + /mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + /mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + dependencies: + mime-db: 1.52.0 + + /mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + dev: true + + /mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + dev: true + + /mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + dev: true + + /min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + dev: true + + /minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@7.4.6: + resolution: {integrity: sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==} + engines: {node: '>=10'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimatch@9.0.1: + resolution: {integrity: sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==} + engines: {node: '>=16 || 14 >=14.17'} + dependencies: + brace-expansion: 2.0.1 + dev: true + + /minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + dev: true + + /minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + dependencies: + yallist: 4.0.0 + dev: true + + /minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + dev: true + + /minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + dev: true + + /mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: true + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 + dev: true + + /mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + dev: true + + /mlly@0.5.17: + resolution: {integrity: sha512-Rn+ai4G+CQXptDFSRNnChEgNr+xAEauYhwRvpPl/UHStTlgkIftplgJRsA2OXPuoUn86K4XAjB26+x5CEvVb6A==} + dependencies: + acorn: 8.8.2 + pathe: 1.1.0 + pkg-types: 1.0.3 + ufo: 1.1.2 + dev: true + + /mlly@1.2.1: + resolution: {integrity: sha512-1aMEByaWgBPEbWV2BOPEMySRrzl7rIHXmQxam4DM8jVjalTQDjpN2ZKOLUrwyhfZQO7IXHml2StcHMhooDeEEQ==} + dependencies: + acorn: 8.8.2 + pathe: 1.1.0 + pkg-types: 1.0.3 + ufo: 1.1.2 + dev: true + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: true + + /mrmime@1.0.1: + resolution: {integrity: sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==} + engines: {node: '>=10'} + dev: true + + /ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /ms@2.1.1: + resolution: {integrity: sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==} + dev: true + + /ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + dev: true + + /ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + dev: true + + /muggle-string@0.2.2: + resolution: {integrity: sha512-YVE1mIJ4VpUMqZObFndk9CJu6DBJR/GB13p3tXuNbwD4XExaI5EOuRl6BHeIDxIqXZVxSfAC+y6U1Z/IxCfKUg==} + dev: true + + /naive-ui@2.34.4(vue@3.3.4): + resolution: {integrity: sha512-aPG8PDfhSzIzn/jSC9y3Jb3Pe2wHJ7F0cFV1EWlbImSrZECeUmoc+fIcOSWbizoztkKfaUAeKwYdMl09MKkj1g==} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@css-render/plugin-bem': 0.15.12(css-render@0.15.12) + '@css-render/vue3-ssr': 0.15.12(vue@3.3.4) + '@types/katex': 0.14.0 + '@types/lodash': 4.14.194 + '@types/lodash-es': 4.17.7 + async-validator: 4.2.5 + css-render: 0.15.12 + date-fns: 2.30.0 + date-fns-tz: 1.3.8(date-fns@2.30.0) + evtd: 0.2.4 + highlight.js: 11.8.0 + lodash: 4.17.21 + lodash-es: 4.17.21 + seemly: 0.3.6 + treemate: 0.3.11 + vdirs: 0.1.8(vue@3.3.4) + vooks: 0.2.12(vue@3.3.4) + vue: 3.3.4 + vueuc: 0.4.51(vue@3.3.4) + dev: false + + /nanoid@3.3.6: + resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + /natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + dev: true + + /natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + dev: true + + /negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + dev: true + + /neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + dev: true + + /node-dir@0.1.17: + resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} + engines: {node: '>= 0.10.5'} + dependencies: + minimatch: 3.1.2 + dev: true + + /node-fetch-native@1.1.1: + resolution: {integrity: sha512-9VvspTSUp2Sxbl+9vbZTlFGq9lHwE8GDVVekxx6YsNd1YH59sb3Ba8v3Y3cD8PkLNcileGGcA21PFjVl0jzDaw==} + dev: true + + /node-fetch@2.6.11: + resolution: {integrity: sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: true + + /node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + dev: true + + /node-releases@2.0.11: + resolution: {integrity: sha512-+M0PwXeU80kRohZ3aT4J/OnR+l9/KD2nVLNNoRgFtnf+umQVFdGBAO2N8+nCnEi0xlh/Wk3zOGC+vNNx+uM79Q==} + dev: true + + /normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.2 + semver: 5.7.1 + validate-npm-package-license: 3.0.4 + dev: true + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: true + + /npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + dependencies: + path-key: 3.1.1 + dev: true + + /npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + dev: true + + /nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: true + + /object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-inspect@1.12.3: + resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + dev: true + + /object-is@1.1.5: + resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + dev: true + + /object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + dev: true + + /object.assign@4.1.4: + resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + has-symbols: 1.0.3 + object-keys: 1.1.1 + dev: true + + /object.values@1.1.6: + resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /ofetch@1.0.1: + resolution: {integrity: sha512-icBz2JYfEpt+wZz1FRoGcrMigjNKjzvufE26m9+yUiacRQRHwnNlGRPiDnW4op7WX/MR6aniwS8xw8jyVelF2g==} + dependencies: + destr: 1.2.2 + node-fetch-native: 1.1.1 + ufo: 1.1.2 + dev: true + + /on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + dependencies: + ee-first: 1.1.1 + dev: true + + /on-headers@1.0.2: + resolution: {integrity: sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==} + engines: {node: '>= 0.8'} + dev: true + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + dependencies: + mimic-fn: 2.1.0 + dev: true + + /open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + dev: true + + /optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.3 + dev: true + + /optionator@0.9.1: + resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} + engines: {node: '>= 0.8.0'} + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.3 + dev: true + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: true + + /p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + dependencies: + yocto-queue: 0.1.0 + dev: true + + /p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + + /p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: true + + /p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + dependencies: + p-limit: 3.1.0 + dev: true + + /p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + dependencies: + aggregate-error: 3.1.0 + dev: true + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: true + + /pako@0.2.9: + resolution: {integrity: sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==} + dev: true + + /parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + dependencies: + callsites: 3.1.0 + dev: true + + /parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + dev: true + + /parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + dependencies: + '@babel/code-frame': 7.21.4 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + dev: true + + /parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + dev: true + + /path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + dev: true + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: true + + /path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: true + + /path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path-to-regexp@0.1.7: + resolution: {integrity: sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==} + dev: true + + /path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + dev: true + + /pathe@0.3.9: + resolution: {integrity: sha512-6Y6s0vT112P3jD8dGfuS6r+lpa0qqNrLyHPOwvXMnyNTQaYiwgau2DP3aNDsR13xqtGj7rrPo+jFUATpU6/s+g==} + dev: true + + /pathe@1.1.0: + resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} + dev: true + + /pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + dev: true + + /peek-stream@1.1.3: + resolution: {integrity: sha512-FhJ+YbOSBb9/rIl2ZeE/QHEsWn7PqNYt8ARAY3kIgNGOk13g9FGyIY6JIl/xB/3TFRVoTv5as0l11weORrTekA==} + dependencies: + buffer-from: 1.1.2 + duplexify: 3.7.1 + through2: 2.0.5 + dev: true + + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true + + /perfect-debounce@1.0.0: + resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} + dev: true + + /picocolors@1.0.0: + resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: true + + /pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + dev: true + + /pinia@2.1.3(typescript@4.9.5)(vue@3.3.4): + resolution: {integrity: sha512-XNA/z/ye4P5rU1pieVmh0g/hSuDO98/a5UC8oSP0DNdvt6YtetJNHTrXwpwsQuflkGT34qKxAEcp7lSxXNjf/A==} + peerDependencies: + '@vue/composition-api': ^1.4.0 + typescript: '>=4.4.4' + vue: ^2.6.14 || ^3.3.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + typescript: + optional: true + dependencies: + '@vue/devtools-api': 6.5.0 + typescript: 4.9.5 + vue: 3.3.4 + vue-demi: 0.14.5(vue@3.3.4) + dev: false + + /pirates@4.0.5: + resolution: {integrity: sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==} + engines: {node: '>= 6'} + dev: true + + /pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + dependencies: + find-up: 3.0.0 + dev: true + + /pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + dev: true + + /pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + dependencies: + find-up: 5.0.0 + dev: true + + /pkg-types@1.0.3: + resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} + dependencies: + jsonc-parser: 3.2.0 + mlly: 1.2.1 + pathe: 1.1.0 + dev: true + + /pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + dev: true + + /polished@4.2.2: + resolution: {integrity: sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ==} + engines: {node: '>=10'} + dependencies: + '@babel/runtime': 7.21.5 + dev: true + + /postcss-selector-parser@6.0.13: + resolution: {integrity: sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ==} + engines: {node: '>=4'} + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + dev: true + + /postcss@8.4.23: + resolution: {integrity: sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==} + engines: {node: ^10 || ^12 || >=14} + dependencies: + nanoid: 3.3.6 + picocolors: 1.0.0 + source-map-js: 1.0.2 + + /prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + dev: true + + /prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + dev: true + + /prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + + /pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + dev: true + + /pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + dev: true + + /pretty-hrtime@1.0.3: + resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} + engines: {node: '>= 0.8'} + dev: true + + /process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + dev: true + + /promise@7.3.1: + resolution: {integrity: sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==} + dependencies: + asap: 2.0.6 + dev: true + + /prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + dev: true + + /prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + dev: true + + /proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + dev: true + + /proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + dev: true + + /pug-attrs@3.0.0: + resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==} + dependencies: + constantinople: 4.0.1 + js-stringify: 1.0.2 + pug-runtime: 3.0.1 + dev: true + + /pug-code-gen@3.0.2: + resolution: {integrity: sha512-nJMhW16MbiGRiyR4miDTQMRWDgKplnHyeLvioEJYbk1RsPI3FuA3saEP8uwnTb2nTJEKBU90NFVWJBk4OU5qyg==} + dependencies: + constantinople: 4.0.1 + doctypes: 1.1.0 + js-stringify: 1.0.2 + pug-attrs: 3.0.0 + pug-error: 2.0.0 + pug-runtime: 3.0.1 + void-elements: 3.1.0 + with: 7.0.2 + dev: true + + /pug-error@2.0.0: + resolution: {integrity: sha512-sjiUsi9M4RAGHktC1drQfCr5C5eriu24Lfbt4s+7SykztEOwVZtbFk1RRq0tzLxcMxMYTBR+zMQaG07J/btayQ==} + dev: true + + /pug-filters@4.0.0: + resolution: {integrity: sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A==} + dependencies: + constantinople: 4.0.1 + jstransformer: 1.0.0 + pug-error: 2.0.0 + pug-walk: 2.0.0 + resolve: 1.22.2 + dev: true + + /pug-lexer@5.0.1: + resolution: {integrity: sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w==} + dependencies: + character-parser: 2.2.0 + is-expression: 4.0.0 + pug-error: 2.0.0 + dev: true + + /pug-linker@4.0.0: + resolution: {integrity: sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw==} + dependencies: + pug-error: 2.0.0 + pug-walk: 2.0.0 + dev: true + + /pug-load@3.0.0: + resolution: {integrity: sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ==} + dependencies: + object-assign: 4.1.1 + pug-walk: 2.0.0 + dev: true + + /pug-parser@6.0.0: + resolution: {integrity: sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw==} + dependencies: + pug-error: 2.0.0 + token-stream: 1.0.0 + dev: true + + /pug-runtime@3.0.1: + resolution: {integrity: sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg==} + dev: true + + /pug-strip-comments@2.0.0: + resolution: {integrity: sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ==} + dependencies: + pug-error: 2.0.0 + dev: true + + /pug-walk@2.0.0: + resolution: {integrity: sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ==} + dev: true + + /pug@3.0.2: + resolution: {integrity: sha512-bp0I/hiK1D1vChHh6EfDxtndHji55XP/ZJKwsRqrz6lRia6ZC2OZbdAymlxdVFwd1L70ebrVJw4/eZ79skrIaw==} + dependencies: + pug-code-gen: 3.0.2 + pug-filters: 4.0.0 + pug-lexer: 5.0.1 + pug-linker: 4.0.0 + pug-load: 3.0.0 + pug-parser: 6.0.0 + pug-runtime: 3.0.1 + pug-strip-comments: 2.0.0 + dev: true + + /pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + + /pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + dev: true + + /punycode@2.3.0: + resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} + engines: {node: '>=6'} + dev: true + + /puppeteer-core@2.1.1: + resolution: {integrity: sha512-n13AWriBMPYxnpbb6bnaY5YoY6rGj8vPLrz6CZF3o0qJNEwlcfJVxBzYZ0NJsQ21UbdJoijPCDrM++SUVEz7+w==} + engines: {node: '>=8.16.0'} + dependencies: + '@types/mime-types': 2.1.1 + debug: 4.3.4 + extract-zip: 1.7.0 + https-proxy-agent: 4.0.0 + mime: 2.6.0 + mime-types: 2.1.35 + progress: 2.0.3 + proxy-from-env: 1.1.0 + rimraf: 2.7.1 + ws: 6.2.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + dev: true + + /qs@6.11.0: + resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /qs@6.11.2: + resolution: {integrity: sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.4 + dev: true + + /queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + dev: true + + /ramda@0.29.0: + resolution: {integrity: sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA==} + dev: true + + /randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + dev: true + + /raw-body@2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: true + + /react-colorful@5.6.1(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1exovf0uGTGyq5mXQT0zgQ80uvj2PCwvF8zY1RN9/vbJVSjSo3fsB/4L3ObbF7u70NduSiK4xu4Y6q1MHoUGEw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + dependencies: + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /react-dom@18.2.0(react@18.2.0): + resolution: {integrity: sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==} + peerDependencies: + react: ^18.2.0 + dependencies: + loose-envify: 1.4.0 + react: 18.2.0 + scheduler: 0.23.0 + dev: true + + /react-inspector@6.0.1(react@18.2.0): + resolution: {integrity: sha512-cxKSeFTf7jpSSVddm66sKdolG90qURAX3g1roTeaN6x0YEbtWc8JpmFN9+yIqLNH2uEkYerWLtJZIXRIFuBKrg==} + peerDependencies: + react: ^16.8.4 || ^17.0.0 || ^18.0.0 + dependencies: + react: 18.2.0 + dev: true + + /react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + dev: true + + /react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + dev: true + + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 + dev: true + + /read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + dev: true + + /read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + dependencies: + '@types/normalize-package-data': 2.4.1 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + dev: true + + /readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + dev: true + + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + dependencies: + picomatch: 2.3.1 + dev: true + + /recast@0.21.5: + resolution: {integrity: sha512-hjMmLaUXAm1hIuTqOdeYObMslq/q+Xff6QE3Y2P+uoHAg2nmVlLBps2hzh1UJDdMtDTMXOFewK6ky51JQIeECg==} + engines: {node: '>= 4'} + dependencies: + ast-types: 0.15.2 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.5.2 + dev: true + + /recast@0.23.2: + resolution: {integrity: sha512-Qv6cPfVZyMOtPszK6PgW70pUgm7gPlFitAPf0Q69rlOA0zLw2XdDcNmPbVGYicFGT9O8I7TZ/0ryJD+6COvIPw==} + engines: {node: '>= 4'} + dependencies: + assert: 2.0.0 + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tslib: 2.5.2 + dev: true + + /rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + dependencies: + resolve: 1.22.2 + dev: true + + /regenerate-unicode-properties@10.1.0: + resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} + engines: {node: '>=4'} + dependencies: + regenerate: 1.4.2 + dev: true + + /regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + dev: true + + /regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + /regenerator-transform@0.15.1: + resolution: {integrity: sha512-knzmNAcuyxV+gQCufkYcvOqX/qIIfHLv0u5x79kRxuGojfYVky1f15TzZEu2Avte8QGepvUNTnLskf8E6X6Vyg==} + dependencies: + '@babel/runtime': 7.21.5 + dev: true + + /regexp-tree@0.1.27: + resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} + hasBin: true + dev: true + + /regexp.prototype.flags@1.5.0: + resolution: {integrity: sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + functions-have-names: 1.2.3 + dev: true + + /regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + dev: true + + /regexpu-core@5.3.2: + resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} + engines: {node: '>=4'} + dependencies: + '@babel/regjsgen': 0.8.0 + regenerate: 1.4.2 + regenerate-unicode-properties: 10.1.0 + regjsparser: 0.9.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.1.0 + dev: true + + /regjsparser@0.9.1: + resolution: {integrity: sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==} + hasBin: true + dependencies: + jsesc: 0.5.0 + dev: true + + /remark-external-links@8.0.0: + resolution: {integrity: sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==} + dependencies: + extend: 3.0.2 + is-absolute-url: 3.0.3 + mdast-util-definitions: 4.0.0 + space-separated-tokens: 1.1.5 + unist-util-visit: 2.0.3 + dev: true + + /remark-slug@6.1.0: + resolution: {integrity: sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ==} + dependencies: + github-slugger: 1.5.0 + mdast-util-to-string: 1.1.0 + unist-util-visit: 2.0.3 + dev: true + + /require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + dev: true + + /requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + dev: true + + /resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + dev: true + + /resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + dev: true + + /resolve@1.22.2: + resolution: {integrity: sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==} + hasBin: true + dependencies: + is-core-module: 2.12.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + dev: true + + /rimraf@2.6.3: + resolution: {integrity: sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + + /rollup-plugin-terser@7.0.2(rollup@2.79.1): + resolution: {integrity: sha512-w3iIaU4OxcF52UUXiZNsNeuXIMDvFrr+ZXK6bFZ0Q60qyVfq4uLptoS4bbq3paG3x216eQllFZX7zt6TIImguQ==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-terser + peerDependencies: + rollup: ^2.0.0 + dependencies: + '@babel/code-frame': 7.21.4 + jest-worker: 26.6.2 + rollup: 2.79.1 + serialize-javascript: 4.0.0 + terser: 5.19.2 + dev: true + + /rollup@2.79.1: + resolution: {integrity: sha512-uKxbd0IhMZOhjAiD5oAFp7BqvkA4Dv47qpOCtaNvng4HBwdbWtdOh8f5nZNuk2rp51PMGk3bzfWu5oayNEuYnw==} + engines: {node: '>=10.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /rollup@3.23.0: + resolution: {integrity: sha512-h31UlwEi7FHihLe1zbk+3Q7z1k/84rb9BSwmBSr/XjOCEaBJ2YyedQDuM0t/kfOS0IxM+vk1/zI9XxYj9V+NJQ==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + dependencies: + queue-microtask: 1.2.3 + dev: true + + /rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + dependencies: + tslib: 2.5.2 + dev: false + + /safe-buffer@5.1.1: + resolution: {integrity: sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==} + dev: true + + /safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex-test@1.0.0: + resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + is-regex: 1.1.4 + dev: true + + /safe-regex@2.1.1: + resolution: {integrity: sha512-rx+x8AMzKb5Q5lQ95Zoi6ZbJqwCLkqi3XuJXp5P3rT8OEc6sZCJG5AE5dU3lsgRr/F4Bs31jSlVN+j5KrsGu9A==} + dependencies: + regexp-tree: 0.1.27 + dev: true + + /safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + dev: true + + /sass@1.62.1: + resolution: {integrity: sha512-NHpxIzN29MXvWiuswfc1W3I0N8SXBd8UR26WntmDlRYf0bSADnwnOjsyMZ3lMezSlArD33Vs3YFhp7dWvL770A==} + engines: {node: '>=14.0.0'} + hasBin: true + dependencies: + chokidar: 3.5.3 + immutable: 4.3.0 + source-map-js: 1.0.2 + dev: true + + /scheduler@0.23.0: + resolution: {integrity: sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==} + dependencies: + loose-envify: 1.4.0 + dev: true + + /scule@0.3.2: + resolution: {integrity: sha512-zIvPdjOH8fv8CgrPT5eqtxHQXmPNnV/vHJYffZhE43KZkvULvpCTvOt1HPlFaCZx287INL9qaqrZg34e8NgI4g==} + dev: true + + /scule@1.0.0: + resolution: {integrity: sha512-4AsO/FrViE/iDNEPaAQlb77tf0csuq27EsVpy6ett584EcRTp6pTDLoGWVxCD77y5iU5FauOvhsI4o1APwPoSQ==} + dev: true + + /seemly@0.3.6: + resolution: {integrity: sha512-lEV5VB8BUKTo/AfktXJcy+JeXns26ylbMkIUco8CYREsQijuz4mrXres2Q+vMLdwkuLxJdIPQ8IlCIxLYm71Yw==} + dev: false + + /semver@5.7.1: + resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} + hasBin: true + dev: true + + /semver@6.3.0: + resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} + hasBin: true + dev: true + + /semver@7.0.0: + resolution: {integrity: sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==} + hasBin: true + dev: true + + /semver@7.5.1: + resolution: {integrity: sha512-Wvss5ivl8TMRZXXESstBA4uR5iXgEN/VC5/sOcuXdVLzcdkz4HWetIoRfG5gb5X+ij/G9rw9YoGn3QoQ8OCSpw==} + engines: {node: '>=10'} + hasBin: true + dependencies: + lru-cache: 6.0.0 + dev: true + + /send@0.18.0: + resolution: {integrity: sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==} + engines: {node: '>= 0.8.0'} + 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 + transitivePeerDependencies: + - supports-color + dev: true + + /serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + dependencies: + randombytes: 2.1.0 + dev: true + + /serve-favicon@2.5.0: + resolution: {integrity: sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA==} + engines: {node: '>= 0.8.0'} + dependencies: + etag: 1.8.1 + fresh: 0.5.2 + ms: 2.1.1 + parseurl: 1.3.3 + safe-buffer: 5.1.1 + dev: true + + /serve-static@1.15.0: + resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} + engines: {node: '>= 0.8.0'} + dependencies: + encodeurl: 1.0.2 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.18.0 + transitivePeerDependencies: + - supports-color + dev: true + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: true + + /setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + dev: true + + /shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + dependencies: + kind-of: 6.0.3 + dev: true + + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + dependencies: + shebang-regex: 3.0.0 + dev: true + + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + dev: true + + /shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + dev: true + + /side-channel@1.0.4: + resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} + dependencies: + call-bind: 1.0.2 + get-intrinsic: 1.2.1 + object-inspect: 1.12.3 + dev: true + + /siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + dev: true + + /signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + dev: true + + /simple-update-notifier@1.1.0: + resolution: {integrity: sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==} + engines: {node: '>=8.10.0'} + dependencies: + semver: 7.0.0 + dev: true + + /sirv@2.0.3: + resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==} + engines: {node: '>= 10'} + dependencies: + '@polka/url': 1.0.0-next.21 + mrmime: 1.0.1 + totalist: 3.0.1 + dev: true + + /sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + dev: true + + /slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + dev: true + + /source-map-js@1.0.2: + resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} + engines: {node: '>=0.10.0'} + + /source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + dev: true + + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + /source-map@0.8.0-beta.0: + resolution: {integrity: sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA==} + engines: {node: '>= 8'} + dependencies: + whatwg-url: 7.1.0 + dev: true + + /sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + dev: true + + /space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + dev: true + + /spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-exceptions@2.3.0: + resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} + dev: true + + /spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + dependencies: + spdx-exceptions: 2.3.0 + spdx-license-ids: 3.0.13 + dev: true + + /spdx-license-ids@3.0.13: + resolution: {integrity: sha512-XkD+zwiqXHikFZm4AX/7JSCXA98U5Db4AFd5XUg/+9UNtnH75+Z9KxtpYiJZx36mUDVOwH83pl7yvCer6ewM3w==} + dev: true + + /sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + dev: true + + /stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + dev: true + + /statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + dev: true + + /std-env@3.3.3: + resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + dev: true + + /stop-iteration-iterator@1.0.0: + resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} + engines: {node: '>= 0.4'} + dependencies: + internal-slot: 1.0.5 + dev: true + + /store2@2.14.2: + resolution: {integrity: sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==} + dev: true + + /storybook@7.0.12: + resolution: {integrity: sha512-HKi7NQQTZhBGEU3KUFxTNGtIZcG8+hokiO5TwcIr7s7smAVKdvj9vY5YGsVkiWF39o+5UtafW1B/i9D8lBFsYg==} + hasBin: true + dependencies: + '@storybook/cli': 7.0.12 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /stream-shift@1.0.1: + resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} + dev: true + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + dev: true + + /string.prototype.matchall@4.0.8: + resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + get-intrinsic: 1.2.1 + has-symbols: 1.0.3 + internal-slot: 1.0.5 + regexp.prototype.flags: 1.5.0 + side-channel: 1.0.4 + dev: true + + /string.prototype.trim@1.2.7: + resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /string.prototype.trimend@1.0.6: + resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /string.prototype.trimstart@1.0.6: + resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + dependencies: + call-bind: 1.0.2 + define-properties: 1.2.0 + es-abstract: 1.21.2 + dev: true + + /string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + dependencies: + safe-buffer: 5.2.1 + dev: true + + /stringify-object@3.3.0: + resolution: {integrity: sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==} + engines: {node: '>=4'} + dependencies: + get-own-enumerable-property-symbols: 3.0.2 + is-obj: 1.0.1 + is-regexp: 1.0.0 + dev: true + + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + dependencies: + ansi-regex: 5.0.1 + dev: true + + /strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + dev: true + + /strip-comments@2.0.1: + resolution: {integrity: sha512-ZprKx+bBLXv067WTCALv8SSz5l2+XhpYCsVtSqlMnkAXMWDq+/ekVbl1ghqP9rUHTzv6sm/DwCOiYutU/yp1fw==} + engines: {node: '>=10'} + dev: true + + /strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + dev: true + + /strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + dependencies: + min-indent: 1.0.1 + dev: true + + /strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + dev: true + + /strip-literal@0.4.2: + resolution: {integrity: sha512-pv48ybn4iE1O9RLgCAN0iU4Xv7RlBTiit6DKmMiErbs9x1wH6vXBs45tWc0H5wUIF6TLTrKweqkmYF/iraQKNw==} + dependencies: + acorn: 8.8.2 + dev: true + + /strip-literal@1.0.1: + resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} + dependencies: + acorn: 8.8.2 + dev: true + + /supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + dependencies: + has-flag: 3.0.0 + dev: true + + /supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /synchronous-promise@2.0.17: + resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} + dev: true + + /tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.0 + tar-stream: 2.2.0 + dev: true + + /tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + dev: true + + /tar@6.1.15: + resolution: {integrity: sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==} + engines: {node: '>=10'} + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + dev: true + + /telejson@7.1.0: + resolution: {integrity: sha512-jFJO4P5gPebZAERPkJsqMAQ0IMA1Hi0AoSfxpnUaV6j6R2SZqlpkbS20U6dEUtA3RUYt2Ak/mTlkQzHH9Rv/hA==} + dependencies: + memoizerific: 1.11.3 + dev: true + + /temp-dir@2.0.0: + resolution: {integrity: sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==} + engines: {node: '>=8'} + dev: true + + /temp@0.8.4: + resolution: {integrity: sha512-s0ZZzd0BzYv5tLSptZooSjK8oj6C+c19p7Vqta9+6NPOf7r+fxq0cJe6/oN4LTC79sy5NY8ucOJNgwsKCSbfqg==} + engines: {node: '>=6.0.0'} + dependencies: + rimraf: 2.6.3 + dev: true + + /tempy@0.6.0: + resolution: {integrity: sha512-G13vtMYPT/J8A4X2SjdtBTphZlrp1gKv6hZiOjw14RCWg6GbHuQBGtjlx75xLbYV/wEc0D7G5K4rxKP/cXk8Bw==} + engines: {node: '>=10'} + dependencies: + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + + /tempy@1.0.1: + resolution: {integrity: sha512-biM9brNqxSc04Ee71hzFbryD11nX7VPhQQY32AdDmjFvodsRFz/3ufeoTZ6uYkRFfGo188tENcASNs3vTdsM0w==} + engines: {node: '>=10'} + dependencies: + del: 6.1.1 + is-stream: 2.0.1 + temp-dir: 2.0.0 + type-fest: 0.16.0 + unique-string: 2.0.0 + dev: true + + /terser@5.19.2: + resolution: {integrity: sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==} + engines: {node: '>=10'} + hasBin: true + dependencies: + '@jridgewell/source-map': 0.3.5 + acorn: 8.10.0 + commander: 2.20.3 + source-map-support: 0.5.21 + dev: true + + /test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.3 + minimatch: 3.1.2 + dev: true + + /text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + dev: true + + /through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + dev: true + + /time-zone@1.0.0: + resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} + engines: {node: '>=4'} + dev: true + + /tinybench@2.5.0: + resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + dev: true + + /tinypool@0.4.0: + resolution: {integrity: sha512-2ksntHOKf893wSAH4z/+JbPpi92esw8Gn9N2deXX+B0EO92hexAVI9GIZZPx7P5aYo5KULfeOSt3kMOmSOy6uA==} + engines: {node: '>=14.0.0'} + dev: true + + /tinyspy@2.1.0: + resolution: {integrity: sha512-7eORpyqImoOvkQJCSkL0d0mB4NHHIFAy4b1u8PHdDa7SjGS2njzl6/lyGoZLm+eyYEtlUmFGE0rFj66SWxZgQQ==} + engines: {node: '>=14.0.0'} + dev: true + + /tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + dev: true + + /to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + dependencies: + is-number: 7.0.0 + dev: true + + /toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + dev: true + + /token-stream@1.0.0: + resolution: {integrity: sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg==} + dev: true + + /totalist@3.0.1: + resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} + engines: {node: '>=6'} + dev: true + + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: true + + /tr46@1.0.1: + resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} + dependencies: + punycode: 2.3.0 + dev: true + + /treemate@0.3.11: + resolution: {integrity: sha512-M8RGFoKtZ8dF+iwJfAJTOH/SM4KluKOKRJpjCMhI8bG3qB74zrFoArKZ62ll0Fr3mqkMJiQOmWYkdYgDeITYQg==} + dev: false + + /ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + dev: true + + /ts-map@1.0.3: + resolution: {integrity: sha512-vDWbsl26LIcPGmDpoVzjEP6+hvHZkBkLW7JpvwbCv/5IYPJlsbzCVXY3wsCeAxAUeTclNOUZxnLdGh3VBD/J6w==} + dev: true + + /tsconfig-paths@3.14.2: + resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + dev: true + + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: true + + /tslib@2.5.2: + resolution: {integrity: sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==} + + /tsutils@3.21.0(typescript@4.9.5): + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + 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' + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + dev: true + + /type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.1.2 + dev: true + + /type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + dependencies: + prelude-ls: 1.2.1 + dev: true + + /type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + dev: true + + /type-fest@0.16.0: + resolution: {integrity: sha512-eaBzG6MxNzEn9kiwvtre90cXaNLkmadMWa1zQMs3XORCXNbsH/OewwbxC5ia9dCxIxnTAsSxXJaa/p5y8DlvJg==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + dev: true + + /type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + dev: true + + /type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + dev: true + + /type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + dev: true + + /type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + dev: true + + /typed-array-length@1.0.4: + resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + dependencies: + call-bind: 1.0.2 + for-each: 0.3.3 + is-typed-array: 1.1.10 + dev: true + + /typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + dev: true + + /typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + /ufo@1.1.2: + resolution: {integrity: sha512-TrY6DsjTQQgyS3E3dBaOXf0TpPD8u9FVrVYmKVegJuFw51n/YB9XPt+U6ydzFG5ZIN7+DIjPbNmXoBj9esYhgQ==} + dev: true + + /uglify-js@3.17.4: + resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} + engines: {node: '>=0.8.0'} + hasBin: true + requiresBuild: true + dev: true + optional: true + + /unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + dependencies: + call-bind: 1.0.2 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + dev: true + + /unconfig@0.3.7: + resolution: {integrity: sha512-1589b7oGa8ILBYpta7TndM5mLHLzHUqBfhszeZxuUBrjO/RoQ52VGVWsS3w0C0GLNxO9RPmqkf6BmIvBApaRdA==} + dependencies: + '@antfu/utils': 0.5.2 + defu: 6.1.2 + jiti: 1.18.2 + dev: true + + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + dev: true + + /unicode-canonical-property-names-ecmascript@2.0.0: + resolution: {integrity: sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ==} + engines: {node: '>=4'} + dev: true + + /unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.0 + unicode-property-aliases-ecmascript: 2.1.0 + dev: true + + /unicode-match-property-value-ecmascript@2.1.0: + resolution: {integrity: sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA==} + engines: {node: '>=4'} + dev: true + + /unicode-property-aliases-ecmascript@2.1.0: + resolution: {integrity: sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==} + engines: {node: '>=4'} + dev: true + + /unimport@0.6.8: + resolution: {integrity: sha512-MWkaPYvN0j+6jfEuiVFhfmy+aOtgAP11CozSbu/I3Cx+8ybjXIueB7GVlKofHabtjzSlPeAvWKJSFjHWsG2JaA==} + dependencies: + '@rollup/pluginutils': 4.2.1 + escape-string-regexp: 5.0.0 + fast-glob: 3.2.12 + local-pkg: 0.4.3 + magic-string: 0.26.7 + mlly: 0.5.17 + pathe: 0.3.9 + scule: 0.3.2 + strip-literal: 0.4.2 + unplugin: 0.9.6 + dev: true + + /unique-string@2.0.0: + resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==} + engines: {node: '>=8'} + dependencies: + crypto-random-string: 2.0.0 + dev: true + + /unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + dev: true + + /unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + dependencies: + '@types/unist': 2.0.6 + dev: true + + /unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 4.1.0 + dev: true + + /unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + dependencies: + '@types/unist': 2.0.6 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + dev: true + + /universalify@2.0.0: + resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} + engines: {node: '>= 10.0.0'} + dev: true + + /unocss@0.51.13(postcss@8.4.23)(rollup@2.79.1)(vite@4.3.5): + resolution: {integrity: sha512-EAhuQ97D7E+EsTdlCL+xoWEsvz46Se9ZAtHhJ+1W+DzMky9qrDLRyR8Caf2TPbz8dw/z0qYhoPr6/aJARG4r0g==} + engines: {node: '>=14'} + peerDependencies: + '@unocss/webpack': 0.51.13 + peerDependenciesMeta: + '@unocss/webpack': + optional: true + dependencies: + '@unocss/astro': 0.51.13(rollup@2.79.1)(vite@4.3.5) + '@unocss/cli': 0.51.13(rollup@2.79.1) + '@unocss/core': 0.51.13 + '@unocss/extractor-arbitrary-variants': 0.51.13 + '@unocss/postcss': 0.51.13(postcss@8.4.23) + '@unocss/preset-attributify': 0.51.13 + '@unocss/preset-icons': 0.51.13 + '@unocss/preset-mini': 0.51.13 + '@unocss/preset-tagify': 0.51.13 + '@unocss/preset-typography': 0.51.13 + '@unocss/preset-uno': 0.51.13 + '@unocss/preset-web-fonts': 0.51.13 + '@unocss/preset-wind': 0.51.13 + '@unocss/reset': 0.51.13 + '@unocss/transformer-attributify-jsx': 0.51.13 + '@unocss/transformer-attributify-jsx-babel': 0.51.13 + '@unocss/transformer-compile-class': 0.51.13 + '@unocss/transformer-directives': 0.51.13 + '@unocss/transformer-variant-group': 0.51.13 + '@unocss/vite': 0.51.13(rollup@2.79.1)(vite@4.3.5) + transitivePeerDependencies: + - postcss + - rollup + - supports-color + - vite + dev: true + + /unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + dev: true + + /unplugin-auto-import@0.10.3(@vueuse/core@8.9.4)(esbuild@0.17.19)(rollup@2.79.1)(vite@4.3.5): + resolution: {integrity: sha512-tODQr7ZBnsBZ9lKaz2mqszKVi/4ALuLtS4gc1xwpcsBav5TCAl0HFSMuai1qL4AkYEwD2HPqK04LocCyK+D0KQ==} + engines: {node: '>=14'} + peerDependencies: + '@vueuse/core': '*' + peerDependenciesMeta: + '@vueuse/core': + optional: true + dependencies: + '@antfu/utils': 0.5.2 + '@rollup/pluginutils': 4.2.1 + '@vueuse/core': 8.9.4(vue@3.3.4) + local-pkg: 0.4.3 + magic-string: 0.26.7 + unimport: 0.6.8 + unplugin: 0.8.1(esbuild@0.17.19)(rollup@2.79.1)(vite@4.3.5) + transitivePeerDependencies: + - esbuild + - rollup + - vite + - webpack + dev: true + + /unplugin-vue-components@0.24.1(rollup@2.79.1)(vue@3.3.4): + resolution: {integrity: sha512-T3A8HkZoIE1Cja95xNqolwza0yD5IVlgZZ1PVAGvVCx8xthmjsv38xWRCtHtwl+rvZyL9uif42SRkDGw9aCfMA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/parser': ^7.15.8 + '@nuxt/kit': ^3.2.2 + vue: 2 || 3 + peerDependenciesMeta: + '@babel/parser': + optional: true + '@nuxt/kit': + optional: true + dependencies: + '@antfu/utils': 0.7.2 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + chokidar: 3.5.3 + debug: 4.3.4 + fast-glob: 3.2.12 + local-pkg: 0.4.3 + magic-string: 0.30.0 + minimatch: 7.4.6 + resolve: 1.22.2 + unplugin: 1.3.1 + vue: 3.3.4 + transitivePeerDependencies: + - rollup + - supports-color + dev: true + + /unplugin-vue-router@0.6.4(rollup@2.79.1)(vue-router@4.2.1)(vue@3.3.4): + resolution: {integrity: sha512-9THVhhtbVFxbsIibjK59oPwMI1UCxRWRPX7azSkTUABsxovlOXJys5SJx0kd/0oKIqNJuYgkRfAgPuO77SqCOg==} + peerDependencies: + vue-router: ^4.1.0 + peerDependenciesMeta: + vue-router: + optional: true + dependencies: + '@babel/types': 7.21.5 + '@rollup/pluginutils': 5.0.2(rollup@2.79.1) + '@vue-macros/common': 1.3.1(rollup@2.79.1)(vue@3.3.4) + ast-walker-scope: 0.4.1 + chokidar: 3.5.3 + fast-glob: 3.2.12 + json5: 2.2.3 + local-pkg: 0.4.3 + mlly: 1.2.1 + pathe: 1.1.0 + scule: 1.0.0 + unplugin: 1.3.1 + vue-router: 4.2.1(vue@3.3.4) + yaml: 2.2.2 + transitivePeerDependencies: + - rollup + - vue + dev: true + + /unplugin@0.10.2: + resolution: {integrity: sha512-6rk7GUa4ICYjae5PrAllvcDeuT8pA9+j5J5EkxbMFaV+SalHhxZ7X2dohMzu6C3XzsMT+6jwR/+pwPNR3uK9MA==} + dependencies: + acorn: 8.8.2 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.4.6 + dev: true + + /unplugin@0.8.1(esbuild@0.17.19)(rollup@2.79.1)(vite@4.3.5): + resolution: {integrity: sha512-o7rUZoPLG1fH4LKinWgb77gDtTE6mw/iry0Pq0Z5UPvZ9+HZ1/4+7fic7t58s8/CGkPrDpGq+RltO+DmswcR4g==} + peerDependencies: + esbuild: '>=0.13' + rollup: ^2.50.0 + vite: ^2.3.0 || ^3.0.0-0 + webpack: 4 || 5 + peerDependenciesMeta: + esbuild: + optional: true + rollup: + optional: true + vite: + optional: true + webpack: + optional: true + dependencies: + acorn: 8.8.2 + chokidar: 3.5.3 + esbuild: 0.17.19 + rollup: 2.79.1 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.4.6 + dev: true + + /unplugin@0.9.6: + resolution: {integrity: sha512-YYLtfoNiie/lxswy1GOsKXgnLJTE27la/PeCGznSItk+8METYZErO+zzV9KQ/hXhPwzIJsfJ4s0m1Rl7ZCWZ4Q==} + dependencies: + acorn: 8.8.2 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.4.6 + dev: true + + /unplugin@1.3.1: + resolution: {integrity: sha512-h4uUTIvFBQRxUKS2Wjys6ivoeofGhxzTe2sRWlooyjHXVttcVfV/JiavNd3d4+jty0SVV0dxGw9AkY9MwiaCEw==} + dependencies: + acorn: 8.8.2 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.5.0 + dev: true + + /untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + dev: true + + /upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + dev: true + + /update-browserslist-db@1.0.11(browserslist@4.21.5): + resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.21.5 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + + /uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + dependencies: + punycode: 2.3.0 + dev: true + + /use-resize-observer@9.1.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-R25VqO9Wb3asSD4eqtcxk8sJalvIOYBqS8MNZlpDSQ4l4xMQxC/J7Id9HoTqPq8FwULIn0PVW+OAqF2dyYbjow==} + peerDependencies: + react: 16.8.0 - 18 + react-dom: 16.8.0 - 18 + dependencies: + '@juggle/resize-observer': 3.4.0 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: true + + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.10 + which-typed-array: 1.1.9 + dev: true + + /utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + dev: true + + /uuid@9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: true + + /validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + dev: true + + /vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + dev: true + + /vdirs@0.1.8(vue@3.3.4): + resolution: {integrity: sha512-H9V1zGRLQZg9b+GdMk8MXDN2Lva0zx72MPahDKc30v+DtwKjfyOSXWRIX4t2mhDubM1H09gPhWeth/BJWPHGUw==} + peerDependencies: + vue: ^3.0.11 + dependencies: + evtd: 0.2.4 + vue: 3.3.4 + dev: false + + /vite-node@0.30.1(@types/node@18.16.14)(sass@1.62.1): + resolution: {integrity: sha512-vTikpU/J7e6LU/8iM3dzBo8ZhEiKZEKRznEMm+mJh95XhWaPrJQraT/QsT2NWmuEf+zgAoMe64PKT7hfZ1Njmg==} + engines: {node: '>=v14.18.0'} + hasBin: true + dependencies: + cac: 6.7.14 + debug: 4.3.4 + mlly: 1.2.1 + pathe: 1.1.0 + picocolors: 1.0.0 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + transitivePeerDependencies: + - '@types/node' + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /vite-plugin-pwa@0.16.4(vite@4.3.5)(workbox-build@7.0.0)(workbox-window@7.0.0): + resolution: {integrity: sha512-lmwHFIs9zI2H9bXJld/zVTbCqCQHZ9WrpyDMqosICDV0FVnCJwniX1NMDB79HGTIZzOQkY4gSZaVTJTw6maz/Q==} + engines: {node: '>=16.0.0'} + peerDependencies: + vite: ^3.1.0 || ^4.0.0 + workbox-build: ^7.0.0 + workbox-window: ^7.0.0 + dependencies: + debug: 4.3.4 + fast-glob: 3.2.12 + pretty-bytes: 6.1.1 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + workbox-build: 7.0.0 + workbox-window: 7.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /vite@4.3.5(@types/node@18.16.14)(sass@1.62.1): + resolution: {integrity: sha512-0gEnL9wiRFxgz40o/i/eTBwm+NEbpUeTWhzKrZDSdKm6nplj+z4lKz8ANDgildxHm47Vg8EUia0aicKbawUVVA==} + engines: {node: ^14.18.0 || >=16.0.0} + hasBin: true + peerDependencies: + '@types/node': '>= 14' + less: '*' + sass: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + sass: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + dependencies: + '@types/node': 18.16.14 + esbuild: 0.17.19 + postcss: 8.4.23 + rollup: 3.23.0 + sass: 1.62.1 + optionalDependencies: + fsevents: 2.3.2 + dev: true + + /vitest@0.30.1(sass@1.62.1): + resolution: {integrity: sha512-y35WTrSTlTxfMLttgQk4rHcaDkbHQwDP++SNwPb+7H8yb13Q3cu2EixrtHzF27iZ8v0XCciSsLg00RkPAzB/aA==} + engines: {node: '>=v14.18.0'} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@vitest/browser': '*' + '@vitest/ui': '*' + happy-dom: '*' + jsdom: '*' + playwright: '*' + safaridriver: '*' + webdriverio: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + playwright: + optional: true + safaridriver: + optional: true + webdriverio: + optional: true + dependencies: + '@types/chai': 4.3.5 + '@types/chai-subset': 1.3.3 + '@types/node': 18.16.14 + '@vitest/expect': 0.30.1 + '@vitest/runner': 0.30.1 + '@vitest/snapshot': 0.30.1 + '@vitest/spy': 0.30.1 + '@vitest/utils': 0.30.1 + acorn: 8.8.2 + acorn-walk: 8.2.0 + cac: 6.7.14 + chai: 4.3.7 + concordance: 5.0.4 + debug: 4.3.4 + local-pkg: 0.4.3 + magic-string: 0.30.0 + pathe: 1.1.0 + picocolors: 1.0.0 + source-map: 0.6.1 + std-env: 3.3.3 + strip-literal: 1.0.1 + tinybench: 2.5.0 + tinypool: 0.4.0 + vite: 4.3.5(@types/node@18.16.14)(sass@1.62.1) + vite-node: 0.30.1(@types/node@18.16.14)(sass@1.62.1) + why-is-node-running: 2.2.2 + transitivePeerDependencies: + - less + - sass + - stylus + - sugarss + - supports-color + - terser + dev: true + + /void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + dev: true + + /vooks@0.2.12(vue@3.3.4): + resolution: {integrity: sha512-iox0I3RZzxtKlcgYaStQYKEzWWGAduMmq+jS7OrNdQo1FgGfPMubGL3uGHOU9n97NIvfFDBGnpSvkWyb/NSn/Q==} + peerDependencies: + vue: ^3.0.0 + dependencies: + evtd: 0.2.4 + vue: 3.3.4 + dev: false + + /vue-demi@0.14.5(vue@3.3.4): + resolution: {integrity: sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + peerDependencies: + '@vue/composition-api': ^1.0.0-rc.1 + vue: ^3.0.0-0 || ^2.6.0 + peerDependenciesMeta: + '@vue/composition-api': + optional: true + dependencies: + vue: 3.3.4 + + /vue-docgen-api@4.72.3(vue@3.3.4): + resolution: {integrity: sha512-76IpEW/pnY0Lfi+NaKkjYZGpEIxqVnDbCbzfZldLt0ldaKz2wvjepvCN1lhxWYtuucziXspFEEfvOY2shrrE3w==} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + ast-types: 0.16.1 + hash-sum: 2.0.0 + lru-cache: 8.0.5 + pug: 3.0.2 + recast: 0.23.2 + ts-map: 1.0.3 + vue-inbrowser-compiler-independent-utils: 4.71.1(vue@3.3.4) + transitivePeerDependencies: + - vue + dev: true + + /vue-eslint-parser@9.3.0(eslint@8.41.0): + resolution: {integrity: sha512-48IxT9d0+wArT1+3wNIy0tascRoywqSUe2E1YalIC1L8jsUGe5aJQItWfRok7DVFGz3UYvzEI7n5wiTXsCMAcQ==} + engines: {node: ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '>=6.0.0' + dependencies: + debug: 4.3.4 + eslint: 8.41.0 + eslint-scope: 7.2.0 + eslint-visitor-keys: 3.4.1 + espree: 9.5.2 + esquery: 1.5.0 + lodash: 4.17.21 + semver: 7.5.1 + transitivePeerDependencies: + - supports-color + dev: true + + /vue-i18n@9.2.2(vue@3.3.4): + resolution: {integrity: sha512-yswpwtj89rTBhegUAv9Mu37LNznyu3NpyLQmozF3i1hYOhwpG8RjcjIFIIfnu+2MDZJGSZPXaKWvnQA71Yv9TQ==} + engines: {node: '>= 14'} + peerDependencies: + vue: ^3.0.0 + dependencies: + '@intlify/core-base': 9.2.2 + '@intlify/shared': 9.2.2 + '@intlify/vue-devtools': 9.2.2 + '@vue/devtools-api': 6.5.0 + vue: 3.3.4 + + /vue-inbrowser-compiler-independent-utils@4.71.1(vue@3.3.4): + resolution: {integrity: sha512-K3wt3iVmNGaFEOUR4JIThQRWfqokxLfnPslD41FDZB2ajXp789+wCqJyGYlIFsvEQ2P61PInw6/ph5iiqg51gg==} + peerDependencies: + vue: '>=2' + dependencies: + vue: 3.3.4 + dev: true + + /vue-inline-svg@3.1.2(vue@3.3.4): + resolution: {integrity: sha512-K01sLANBnjosObee4JrBu/igXpYIFhQfy4EcEyVWxEWf6nmrxp7Isz6pmeRCsWx6XGrGWfrQH3uNwt4nOmrFdA==} + peerDependencies: + vue: ^3 + dependencies: + vue: 3.3.4 + dev: false + + /vue-router@4.2.1(vue@3.3.4): + resolution: {integrity: sha512-nW28EeifEp8Abc5AfmAShy5ZKGsGzjcnZ3L1yc2DYUo+MqbBClrRP9yda3dIekM4I50/KnEwo1wkBLf7kHH5Cw==} + peerDependencies: + vue: ^3.2.0 + dependencies: + '@vue/devtools-api': 6.5.0 + vue: 3.3.4 + + /vue-template-compiler@2.7.14: + resolution: {integrity: sha512-zyA5Y3ArvVG0NacJDkkzJuPQDF8RFeRlzV2vLeSnhSpieO6LK2OVbdLPi5MPPs09Ii+gMO8nY4S3iKQxBxDmWQ==} + dependencies: + de-indent: 1.0.2 + he: 1.2.0 + dev: true + + /vue-tsc@1.6.4(typescript@4.9.5): + resolution: {integrity: sha512-8rg8S1AhRJ6/WriENQEhyqH5wsxSxuD5iaD+QnkZn2ArZ6evlhqfBAIcVN8mfSyCV9DeLkQXkOSv/MaeJiJPAQ==} + hasBin: true + peerDependencies: + typescript: '*' + dependencies: + '@volar/vue-language-core': 1.6.4 + '@volar/vue-typescript': 1.6.4(typescript@4.9.5) + semver: 7.5.1 + typescript: 4.9.5 + dev: true + + /vue@3.3.4: + resolution: {integrity: sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==} + dependencies: + '@vue/compiler-dom': 3.3.4 + '@vue/compiler-sfc': 3.3.4 + '@vue/runtime-dom': 3.3.4 + '@vue/server-renderer': 3.3.4(vue@3.3.4) + '@vue/shared': 3.3.4 + + /vueuc@0.4.51(vue@3.3.4): + resolution: {integrity: sha512-pLiMChM4f+W8czlIClGvGBYo656lc2Y0/mXFSCydcSmnCR1izlKPGMgiYBGjbY9FDkFG8a2HEVz7t0DNzBWbDw==} + peerDependencies: + vue: ^3.0.11 + dependencies: + '@css-render/vue3-ssr': 0.15.12(vue@3.3.4) + '@juggle/resize-observer': 3.4.0 + css-render: 0.15.12 + evtd: 0.2.4 + seemly: 0.3.6 + vdirs: 0.1.8(vue@3.3.4) + vooks: 0.2.12(vue@3.3.4) + vue: 3.3.4 + dev: false + + /walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + dependencies: + makeerror: 1.0.12 + dev: true + + /watchpack@2.4.0: + resolution: {integrity: sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==} + engines: {node: '>=10.13.0'} + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + dev: true + + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: true + + /webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + dev: true + + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: true + + /webpack-virtual-modules@0.4.6: + resolution: {integrity: sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA==} + dev: true + + /webpack-virtual-modules@0.5.0: + resolution: {integrity: sha512-kyDivFZ7ZM0BVOUteVbDFhlRt7Ah/CSPwJdi8hBpkK7QLumUqdLtVfm/PX/hkcnrvr0i77fO5+TjZ94Pe+C9iw==} + dev: true + + /well-known-symbols@2.0.0: + resolution: {integrity: sha512-ZMjC3ho+KXo0BfJb7JgtQ5IBuvnShdlACNkKkdsqBmYw3bPAaJfPeYUo6tLUaT5tG/Gkh7xkpBhKRQ9e7pyg9Q==} + engines: {node: '>=6'} + dev: true + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: true + + /whatwg-url@7.1.0: + resolution: {integrity: sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg==} + dependencies: + lodash.sortby: 4.7.0 + tr46: 1.0.1 + webidl-conversions: 4.0.2 + dev: true + + /which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + dev: true + + /which-collection@1.0.1: + resolution: {integrity: sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A==} + dependencies: + is-map: 2.0.2 + is-set: 2.0.2 + is-weakmap: 2.0.1 + is-weakset: 2.0.2 + dev: true + + /which-typed-array@1.1.9: + resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.5 + call-bind: 1.0.2 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.0 + is-typed-array: 1.1.10 + dev: true + + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: true + + /why-is-node-running@2.2.2: + resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} + engines: {node: '>=8'} + hasBin: true + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + dev: true + + /wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + dependencies: + string-width: 4.2.3 + dev: true + + /widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + dependencies: + string-width: 4.2.3 + dev: true + + /with@7.0.2: + resolution: {integrity: sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w==} + engines: {node: '>= 10.0.0'} + dependencies: + '@babel/parser': 7.21.9 + '@babel/types': 7.21.5 + assert-never: 1.2.1 + babel-walk: 3.0.0-canary-5 + dev: true + + /word-wrap@1.2.3: + resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} + engines: {node: '>=0.10.0'} + dev: true + + /wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + dev: true + + /workbox-background-sync@7.0.0: + resolution: {integrity: sha512-S+m1+84gjdueM+jIKZ+I0Lx0BDHkk5Nu6a3kTVxP4fdj3gKouRNmhO8H290ybnJTOPfBDtTMXSQA/QLTvr7PeA==} + dependencies: + idb: 7.1.1 + workbox-core: 7.0.0 + dev: true + + /workbox-broadcast-update@7.0.0: + resolution: {integrity: sha512-oUuh4jzZrLySOo0tC0WoKiSg90bVAcnE98uW7F8GFiSOXnhogfNDGZelPJa+6KpGBO5+Qelv04Hqx2UD+BJqNQ==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-build@7.0.0: + resolution: {integrity: sha512-CttE7WCYW9sZC+nUYhQg3WzzGPr4IHmrPnjKiu3AMXsiNQKx+l4hHl63WTrnicLmKEKHScWDH8xsGBdrYgtBzg==} + engines: {node: '>=16.0.0'} + dependencies: + '@apideck/better-ajv-errors': 0.3.6(ajv@8.12.0) + '@babel/core': 7.21.8 + '@babel/preset-env': 7.21.5(@babel/core@7.21.8) + '@babel/runtime': 7.21.5 + '@rollup/plugin-babel': 5.3.1(@babel/core@7.21.8)(rollup@2.79.1) + '@rollup/plugin-node-resolve': 11.2.1(rollup@2.79.1) + '@rollup/plugin-replace': 2.4.2(rollup@2.79.1) + '@surma/rollup-plugin-off-main-thread': 2.2.3 + ajv: 8.12.0 + common-tags: 1.8.2 + fast-json-stable-stringify: 2.1.0 + fs-extra: 9.1.0 + glob: 7.2.3 + lodash: 4.17.21 + pretty-bytes: 5.6.0 + rollup: 2.79.1 + rollup-plugin-terser: 7.0.2(rollup@2.79.1) + source-map: 0.8.0-beta.0 + stringify-object: 3.3.0 + strip-comments: 2.0.1 + tempy: 0.6.0 + upath: 1.2.0 + workbox-background-sync: 7.0.0 + workbox-broadcast-update: 7.0.0 + workbox-cacheable-response: 7.0.0 + workbox-core: 7.0.0 + workbox-expiration: 7.0.0 + workbox-google-analytics: 7.0.0 + workbox-navigation-preload: 7.0.0 + workbox-precaching: 7.0.0 + workbox-range-requests: 7.0.0 + workbox-recipes: 7.0.0 + workbox-routing: 7.0.0 + workbox-strategies: 7.0.0 + workbox-streams: 7.0.0 + workbox-sw: 7.0.0 + workbox-window: 7.0.0 + transitivePeerDependencies: + - '@types/babel__core' + - supports-color + dev: true + + /workbox-cacheable-response@7.0.0: + resolution: {integrity: sha512-0lrtyGHn/LH8kKAJVOQfSu3/80WDc9Ma8ng0p2i/5HuUndGttH+mGMSvOskjOdFImLs2XZIimErp7tSOPmu/6g==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-core@7.0.0: + resolution: {integrity: sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ==} + dev: true + + /workbox-expiration@7.0.0: + resolution: {integrity: sha512-MLK+fogW+pC3IWU9SFE+FRStvDVutwJMR5if1g7oBJx3qwmO69BNoJQVaMXq41R0gg3MzxVfwOGKx3i9P6sOLQ==} + dependencies: + idb: 7.1.1 + workbox-core: 7.0.0 + dev: true + + /workbox-google-analytics@7.0.0: + resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==} + dependencies: + workbox-background-sync: 7.0.0 + workbox-core: 7.0.0 + workbox-routing: 7.0.0 + workbox-strategies: 7.0.0 + dev: true + + /workbox-navigation-preload@7.0.0: + resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-precaching@7.0.0: + resolution: {integrity: sha512-EC0vol623LJqTJo1mkhD9DZmMP604vHqni3EohhQVwhJlTgyKyOkMrZNy5/QHfOby+39xqC01gv4LjOm4HSfnA==} + dependencies: + workbox-core: 7.0.0 + workbox-routing: 7.0.0 + workbox-strategies: 7.0.0 + dev: true + + /workbox-range-requests@7.0.0: + resolution: {integrity: sha512-SxAzoVl9j/zRU9OT5+IQs7pbJBOUOlriB8Gn9YMvi38BNZRbM+RvkujHMo8FOe9IWrqqwYgDFBfv6sk76I1yaQ==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-recipes@7.0.0: + resolution: {integrity: sha512-DntcK9wuG3rYQOONWC0PejxYYIDHyWWZB/ueTbOUDQgefaeIj1kJ7pdP3LZV2lfrj8XXXBWt+JDRSw1lLLOnww==} + dependencies: + workbox-cacheable-response: 7.0.0 + workbox-core: 7.0.0 + workbox-expiration: 7.0.0 + workbox-precaching: 7.0.0 + workbox-routing: 7.0.0 + workbox-strategies: 7.0.0 + dev: true + + /workbox-routing@7.0.0: + resolution: {integrity: sha512-8YxLr3xvqidnbVeGyRGkaV4YdlKkn5qZ1LfEePW3dq+ydE73hUUJJuLmGEykW3fMX8x8mNdL0XrWgotcuZjIvA==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-strategies@7.0.0: + resolution: {integrity: sha512-dg3qJU7tR/Gcd/XXOOo7x9QoCI9nk74JopaJaYAQ+ugLi57gPsXycVdBnYbayVj34m6Y8ppPwIuecrzkpBVwbA==} + dependencies: + workbox-core: 7.0.0 + dev: true + + /workbox-streams@7.0.0: + resolution: {integrity: sha512-moVsh+5to//l6IERWceYKGiftc+prNnqOp2sgALJJFbnNVpTXzKISlTIsrWY+ogMqt+x1oMazIdHj25kBSq/HQ==} + dependencies: + workbox-core: 7.0.0 + workbox-routing: 7.0.0 + dev: true + + /workbox-sw@7.0.0: + resolution: {integrity: sha512-SWfEouQfjRiZ7GNABzHUKUyj8pCoe+RwjfOIajcx6J5mtgKkN+t8UToHnpaJL5UVVOf5YhJh+OHhbVNIHe+LVA==} + dev: true + + /workbox-window@7.0.0: + resolution: {integrity: sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA==} + dependencies: + '@types/trusted-types': 2.0.3 + workbox-core: 7.0.0 + dev: true + + /wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: true + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true + + /write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + dev: true + + /ws@6.2.2: + resolution: {integrity: sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dependencies: + async-limiter: 1.0.1 + dev: true + + /ws@8.13.0: + resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + 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 + dev: true + + /xml-name-validator@4.0.0: + resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} + engines: {node: '>=12'} + dev: true + + /xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + dev: true + + /yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + dev: true + + /yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + dev: true + + /yaml-eslint-parser@0.3.2: + resolution: {integrity: sha512-32kYO6kJUuZzqte82t4M/gB6/+11WAuHiEnK7FreMo20xsCKPeFH5tDBU7iWxR7zeJpNnMXfJyXwne48D0hGrg==} + dependencies: + eslint-visitor-keys: 1.3.0 + lodash: 4.17.21 + yaml: 1.10.2 + dev: true + + /yaml-eslint-parser@1.2.2: + resolution: {integrity: sha512-pEwzfsKbTrB8G3xc/sN7aw1v6A6c/pKxLAkjclnAyo5g5qOh6eL9WGu0o3cSDQZKrTNk4KL4lQSwZW+nBkANEg==} + engines: {node: ^14.17.0 || >=16.0.0} + dependencies: + eslint-visitor-keys: 3.4.1 + lodash: 4.17.21 + yaml: 2.2.2 + dev: true + + /yaml@1.10.2: + resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} + engines: {node: '>= 6'} + dev: true + + /yaml@2.2.2: + resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==} + engines: {node: '>= 14'} + dev: true + + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: true + + /yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + dev: true + + /yocto-queue@1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true diff --git a/webui/public/images/AutoBangumi-dark.svg b/webui/public/images/AutoBangumi-dark.svg new file mode 100644 index 00000000..a0cc6a19 --- /dev/null +++ b/webui/public/images/AutoBangumi-dark.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webui/public/images/AutoBangumi.svg b/webui/public/images/AutoBangumi.svg new file mode 100644 index 00000000..369c5ec9 --- /dev/null +++ b/webui/public/images/AutoBangumi.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/webui/public/images/RSS.svg b/webui/public/images/RSS.svg new file mode 100644 index 00000000..fb0e4a39 --- /dev/null +++ b/webui/public/images/RSS.svg @@ -0,0 +1,3 @@ + + + diff --git a/webui/public/images/apple-touch-icon-180x180.png b/webui/public/images/apple-touch-icon-180x180.png new file mode 100644 index 00000000..9464d94f Binary files /dev/null and b/webui/public/images/apple-touch-icon-180x180.png differ diff --git a/webui/public/images/logo-light.svg b/webui/public/images/logo-light.svg new file mode 100644 index 00000000..62a5106c --- /dev/null +++ b/webui/public/images/logo-light.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/webui/public/images/logo.svg b/webui/public/images/logo.svg new file mode 100644 index 00000000..3c15fe51 --- /dev/null +++ b/webui/public/images/logo.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/webui/public/images/pwa-192.png b/webui/public/images/pwa-192.png new file mode 100644 index 00000000..1c97fdd0 Binary files /dev/null and b/webui/public/images/pwa-192.png differ diff --git a/webui/public/images/pwa-512.png b/webui/public/images/pwa-512.png new file mode 100644 index 00000000..3235fada Binary files /dev/null and b/webui/public/images/pwa-512.png differ diff --git a/webui/public/robots.txt b/webui/public/robots.txt new file mode 100644 index 00000000..84a594f6 --- /dev/null +++ b/webui/public/robots.txt @@ -0,0 +1,39 @@ +# robots.txt generated at http://tool.chinaz.com/robots/ +User-agent: Baiduspider +Disallow: / +User-agent: Sosospider +Disallow: / +User-agent: sogou spider +Disallow: / +User-agent: YodaoBot +Disallow: / +User-agent: Googlebot +Disallow: / +User-agent: Bingbot +Disallow: / +User-agent: Slurp +Disallow: / +User-agent: Teoma +Disallow: / +User-agent: ia_archiver +Disallow: / +User-agent: twiceler +Disallow: / +User-agent: MSNBot +Disallow: / +User-agent: Scrubby +Disallow: / +User-agent: Robozilla +Disallow: / +User-agent: Gigabot +Disallow: / +User-agent: googlebot-image +Disallow: / +User-agent: googlebot-mobile +Disallow: / +User-agent: yahoo-mmcrawler +Disallow: / +User-agent: yahoo-blogs/v3.9 +Disallow: / +User-agent: psbot +Disallow: / \ No newline at end of file diff --git a/webui/src/App.vue b/webui/src/App.vue new file mode 100644 index 00000000..373f747d --- /dev/null +++ b/webui/src/App.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/webui/src/api/auth.ts b/webui/src/api/auth.ts new file mode 100644 index 00000000..dade168b --- /dev/null +++ b/webui/src/api/auth.ts @@ -0,0 +1,41 @@ +import type { LoginSuccess, Logout, Update } from '#/auth'; + +export const apiAuth = { + async login(username: string, password: string) { + const formData = new URLSearchParams({ + username, + password, + }); + + const { data } = await axios.post( + 'api/v1/auth/login', + formData, + { + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + } + ); + + return data; + }, + + async refresh() { + const { data } = await axios.get('api/v1/auth/refresh_token'); + return data; + }, + + async logout() { + const { data } = await axios.get('api/v1/auth/logout'); + return data.message === 'logout success'; + }, + + async update(username: string, password: string) { + const { data } = await axios.post('api/v1/auth/update', { + username, + password, + }); + + return data; + }, +}; diff --git a/webui/src/api/bangumi.ts b/webui/src/api/bangumi.ts new file mode 100644 index 00000000..5f0d0c21 --- /dev/null +++ b/webui/src/api/bangumi.ts @@ -0,0 +1,129 @@ +import type { BangumiAPI, BangumiRule } from '#/bangumi'; +import type { ApiSuccess } from '#/api'; + + +export const apiBangumi = { + /** + * 获取所有 bangumi 数据 + * @returns 所有 bangumi 数据 + */ + async getAll() { + const { data } = await axios.get('api/v1/bangumi/get/all'); + const result: BangumiRule[] = data.map((bangumi) => ( + { + ...bangumi, + filter: bangumi.filter.split(','), + rss_link: bangumi.rss_link.split(','), + } + )); + return result; + }, + + /** + * 获取指定 bangumiId 的规则 + * @param bangumiId bangumi id + * @returns 指定 bangumi 的规则 + */ + async getRule(bangumiId: number) { + const { data } = await axios.get( + `api/v1/bangumi/get/${bangumiId}` + ); + const result: BangumiRule = { + ...data, + filter: data.filter.split(','), + rss_link: data.rss_link.split(','), + } + return result; + }, + + /** + * 更新指定 bangumiId 的规则 + * @param bangumiId - 需要更新的 bangumi 的 id + * @param bangumiRule + * @returns axios 请求返回的数据 + */ + async updateRule(bangumiId: number, bangumiRule: BangumiRule) { + const rule: BangumiAPI = { + ...bangumiRule, + filter: bangumiRule.filter.join(','), + rss_link: bangumiRule.rss_link.join(','), + } + const post = omit(rule, ['id']) + const { data } = await axios.patch< ApiSuccess >( + `api/v1/bangumi/update/${bangumiId}`, + post + ); + return data; + }, + + /** + * 删除指定 bangumiId 的数据库规则,会在重新匹配到后重建 + * @param bangumiId - 需要删除的 bangumi 的 id + * @param file - 是否同时删除关联文件。 + * @returns axios 请求返回的数据 + */ + async deleteRule(bangumiId: number | number[], file: boolean) { + let url = 'api/v1/bangumi/delete'; + let ids: undefined | number[]; + + if (typeof bangumiId === 'number') { + url = `${url}/${bangumiId}`; + } else { + url = `${url}/many`; + ids = bangumiId; + } + + const { data } = await axios.delete< ApiSuccess >(url, { + data: ids, + params: { + file, + }, + }); + return data; + }, + + /** + * 删除指定 bangumiId 的规则。如果 file 为 true,则同时删除关联文件。 + * @param bangumiId - 需要删除规则的 bangumi 的 id。 + * @param file - 是否同时删除关联文件。 + * @returns axios 请求返回的数据 + */ + async disableRule(bangumiId: number | number[], file: boolean) { + let url = 'api/v1/bangumi/disable'; + let ids: undefined | number[]; + + if (typeof bangumiId === 'number') { + url = `${url}/${bangumiId}`; + } else { + url = `${url}/many`; + ids = bangumiId; + } + + const { data } = await axios.delete< ApiSuccess >(url, { + data: ids, + params: { + file, + }, + }); + return data; + }, + + /** + * 启用指定 bangumiId 的规则 + * @param bangumiId - 需要启用的 bangumi 的 id + */ + async enableRule(bangumiId: number) { + const { data } = await axios.get< ApiSuccess >( + `api/v1/bangumi/enable/${bangumiId}` + ); + return data; + }, + + /** + * 重置所有 bangumi 数据 + */ + async resetAll() { + const { data } = await axios.get< ApiSuccess >('api/v1/bangumi/reset/all'); + return data; + }, +}; diff --git a/webui/src/api/check.ts b/webui/src/api/check.ts new file mode 100644 index 00000000..a59a3a73 --- /dev/null +++ b/webui/src/api/check.ts @@ -0,0 +1,10 @@ +export const apiCheck = { + /** + * 检测下载器 + */ + async downloader() { + const { data } = await axios.get('api/v1/check/downloader'); + return data; + }, + +} \ No newline at end of file diff --git a/webui/src/api/config.ts b/webui/src/api/config.ts new file mode 100644 index 00000000..4fa5d6b1 --- /dev/null +++ b/webui/src/api/config.ts @@ -0,0 +1,24 @@ +import type { Config } from '#/config'; +import type { ApiSuccess } from '#/api'; + +export const apiConfig = { + /** + * 获取 config 数据 + */ + async getConfig() { + const { data } = await axios.get('api/v1/config/get'); + return data; + }, + + /** + * 更新 config 数据 + * @param newConfig - 需要更新的 config + */ + async updateConfig(newConfig: Config) { + const { data } = await axios.patch( + 'api/v1/config/update', + newConfig + ); + return data; + }, +}; diff --git a/webui/src/api/download.ts b/webui/src/api/download.ts new file mode 100644 index 00000000..29594559 --- /dev/null +++ b/webui/src/api/download.ts @@ -0,0 +1,57 @@ +import type { BangumiAPI, BangumiRule } from '#/bangumi'; +import type { RSS } from '#/rss'; +import type { ApiError, ApiSuccess } from '#/api'; + +export const apiDownload = { + /** + * 解析 RSS 链接 + * @param rss_item - RSS 链接 + */ + async analysis(rss_item: RSS) { + const { data } = await axios.post( + 'api/v1/rss/analysis', + rss_item + ); + + const result: BangumiRule = { + ...data, + filter: data.filter.split(','), + rss_link: data.rss_link.split(','), + } + return result; + }, + + /** + * 旧番 + * @param bangumiData - Bangumi 数据 + */ + async collection(bangumiData: BangumiRule) { + const postData: BangumiAPI = { + ...bangumiData, + filter: bangumiData.filter.join(','), + rss_link: bangumiData.rss_link.join(','), + } + const { data } = await axios.post( + 'api/v1/rss/collect', + postData + ); + return data; + }, + + /** + * 新番 + * @param bangumiData - Bangumi 数据 + */ + async subscribe(bangumiData: BangumiRule) { + const postData: BangumiAPI = { + ...bangumiData, + filter: bangumiData.filter.join(','), + rss_link: bangumiData.rss_link.join(','), + } + const { data } = await axios.post( + 'api/v1/rss/subscribe', + postData + ); + return data; + }, +}; diff --git a/webui/src/api/log.ts b/webui/src/api/log.ts new file mode 100644 index 00000000..b7492153 --- /dev/null +++ b/webui/src/api/log.ts @@ -0,0 +1,13 @@ +import type { ApiSuccess } from "#/api"; + +export const apiLog = { + async getLog() { + const { data } = await axios.get('api/v1/log'); + return data; + }, + + async clearLog() { + const { data } = await axios.get('api/v1/log/clear'); + return data; + }, +}; diff --git a/webui/src/api/program.ts b/webui/src/api/program.ts new file mode 100644 index 00000000..d8ce5f0b --- /dev/null +++ b/webui/src/api/program.ts @@ -0,0 +1,47 @@ +import type { ApiSuccess } from "#/api"; + + +export const apiProgram = { + /** + * 重启 + */ + async restart() { + const { data } = await axios.get('api/v1/restart'); + return data; + }, + + /** + * 启动 + */ + async start() { + const { data } = await axios.get('api/v1/start'); + return data; + }, + + /** + * 停止 + */ + async stop() { + const { data } = await axios.get('api/v1/stop'); + return data; + }, + + /** + * 状态 + */ + async status() { + const { data } = await axios.get<{ status: boolean; version: string }>( + 'api/v1/status' + ); + + return data!; + }, + + /** + * 终止 + */ + async shutdown() { + const { data } = await axios.get('api/v1/shutdown'); + return data; + }, +}; diff --git a/webui/src/api/rss.ts b/webui/src/api/rss.ts new file mode 100644 index 00000000..c92b0889 --- /dev/null +++ b/webui/src/api/rss.ts @@ -0,0 +1,60 @@ +import type { RSS } from '#/rss'; +import type { Torrent } from '#/torrent'; +import type { ApiSuccess } from '#/api'; + +export const apiRSS = { + async get() { + const { data } = await axios.get('api/v1/rss'); + return data!; + }, + + async add(rss: RSS) { + const { data } = await axios.post('api/v1/rss/add', rss); + return data; + }, + + async delete(rss_id: number) { + const { data } = await axios.delete(`api/v1/rss/delete/${rss_id}`); + return data!; + }, + + async deleteMany(rss_list: number[]) { + const { data } = await axios.post(`api/v1/rss/delete/many`, rss_list); + return data!; + }, + + async disable(rss_id: number) { + const { data } = await axios.patch(`api/v1/rss/disable/${rss_id}`); + return data!; + }, + + async disableMany(rss_list: number[]) { + const { data } = await axios.post(`api/v1/rss/disable/many`, rss_list); + return data!; + }, + + async update(rss_id: number, rss: RSS) { + const { data } = await axios.patch(`api/v1/rss/update/${rss_id}`, rss); + return data!; + }, + + async enableMany(rss_list: number[]) { + const { data } = await axios.post(`api/v1/rss/enable/many`, rss_list); + return data!; + }, + + async refreshAll() { + const { data } = await axios.get('api/v1/rss/refresh/all'); + return data!; + }, + + async refresh(rss_id: number) { + const { data } = await axios.get(`api/v1/rss/refresh/${rss_id}`); + return data!; + }, + + async getTorrent(rss_id: number) { + const { data } = await axios.get(`api/v1/rss/torrent/${rss_id}`); + return data!; + }, +}; diff --git a/webui/src/api/search.ts b/webui/src/api/search.ts new file mode 100644 index 00000000..61f26591 --- /dev/null +++ b/webui/src/api/search.ts @@ -0,0 +1,52 @@ +import { + Observable, +} from 'rxjs'; + +import type { BangumiRule, BangumiAPI } from '#/bangumi'; + +export const apiSearch = { + /** + * 番剧搜索接口是 Server Send 流式数据,每条是一个 Bangumi JSON 字符串, + * 使用接口方式是监听连接消息后,转为 Observable 配合外层调用时 switchMap 订阅使用 + */ + get(keyword: string, site = 'mikan'): Observable { + const bangumiInfo$ = new Observable(observer => { + const eventSource = new EventSource( + `api/v1/search/bangumi?site=${site}&keywords=${encodeURIComponent(keyword)}`, + { withCredentials: true }, + ); + + eventSource.onmessage = ev => { + try { + const apiData: BangumiAPI = JSON.parse(ev.data); + const data: BangumiRule = { + ...apiData, + filter: apiData.filter.split(','), + rss_link: apiData.rss_link.split(','), + } + observer.next(data); + } catch (error) { + console.error('[/search/bangumi] Parse Error |', { keyword }, 'response:', ev.data) + } + }; + + eventSource.onerror = ev => { + console.error('[/search/bangumi] Server Error |', { keyword }, 'error:', ev) + // 目前后端搜索完成关闭连接时会触发 error 事件,前端手动调用 close 不再自动重连 + eventSource.close(); + }; + + return () => { + eventSource.close(); + }; + }); + + return bangumiInfo$; + }, + + async getProvider() { + const { data } = await axios.get('api/v1/search/provider'); + return data; + } +}; + diff --git a/webui/src/components/ab-add-rss.vue b/webui/src/components/ab-add-rss.vue new file mode 100644 index 00000000..67925e87 --- /dev/null +++ b/webui/src/components/ab-add-rss.vue @@ -0,0 +1,171 @@ + + + diff --git a/webui/src/components/ab-bangumi-card.vue b/webui/src/components/ab-bangumi-card.vue new file mode 100644 index 00000000..fd5a0344 --- /dev/null +++ b/webui/src/components/ab-bangumi-card.vue @@ -0,0 +1,134 @@ + + + + + \ No newline at end of file diff --git a/webui/src/components/ab-change-account.vue b/webui/src/components/ab-change-account.vue new file mode 100644 index 00000000..a2285fcb --- /dev/null +++ b/webui/src/components/ab-change-account.vue @@ -0,0 +1,43 @@ + + + diff --git a/webui/src/components/ab-container.vue b/webui/src/components/ab-container.vue new file mode 100644 index 00000000..e4414e6a --- /dev/null +++ b/webui/src/components/ab-container.vue @@ -0,0 +1,33 @@ + + + diff --git a/webui/src/components/ab-edit-rule.vue b/webui/src/components/ab-edit-rule.vue new file mode 100644 index 00000000..528efb64 --- /dev/null +++ b/webui/src/components/ab-edit-rule.vue @@ -0,0 +1,131 @@ + + + diff --git a/webui/src/components/ab-fold-panel.vue b/webui/src/components/ab-fold-panel.vue new file mode 100644 index 00000000..678941f4 --- /dev/null +++ b/webui/src/components/ab-fold-panel.vue @@ -0,0 +1,41 @@ + + + diff --git a/webui/src/components/ab-label.vue b/webui/src/components/ab-label.vue new file mode 100644 index 00000000..1eaa20af --- /dev/null +++ b/webui/src/components/ab-label.vue @@ -0,0 +1,26 @@ + + + diff --git a/webui/src/components/ab-popup.vue b/webui/src/components/ab-popup.vue new file mode 100644 index 00000000..b7c036ed --- /dev/null +++ b/webui/src/components/ab-popup.vue @@ -0,0 +1,69 @@ + + + diff --git a/webui/src/components/ab-rss-item.vue b/webui/src/components/ab-rss-item.vue new file mode 100644 index 00000000..0a7435da --- /dev/null +++ b/webui/src/components/ab-rss-item.vue @@ -0,0 +1,68 @@ + + + + + \ No newline at end of file diff --git a/webui/src/components/ab-rule.vue b/webui/src/components/ab-rule.vue new file mode 100644 index 00000000..0e1233f2 --- /dev/null +++ b/webui/src/components/ab-rule.vue @@ -0,0 +1,66 @@ + + + diff --git a/webui/src/components/ab-search-bar.vue b/webui/src/components/ab-search-bar.vue new file mode 100644 index 00000000..4dfaff2b --- /dev/null +++ b/webui/src/components/ab-search-bar.vue @@ -0,0 +1,95 @@ + + + + + + + \ No newline at end of file diff --git a/webui/src/components/ab-setting.vue b/webui/src/components/ab-setting.vue new file mode 100644 index 00000000..e1784b86 --- /dev/null +++ b/webui/src/components/ab-setting.vue @@ -0,0 +1,45 @@ + + + diff --git a/webui/src/components/ab-status-bar.vue b/webui/src/components/ab-status-bar.vue new file mode 100644 index 00000000..6d5146f8 --- /dev/null +++ b/webui/src/components/ab-status-bar.vue @@ -0,0 +1,101 @@ + + + diff --git a/webui/src/components/basic/ab-add.stories.ts b/webui/src/components/basic/ab-add.stories.ts new file mode 100644 index 00000000..bf585736 --- /dev/null +++ b/webui/src/components/basic/ab-add.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbAdd from './ab-add.vue'; + +const meta: Meta = { + title: 'basic/ab-add', + component: AbAdd, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbAdd }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-add.vue b/webui/src/components/basic/ab-add.vue new file mode 100644 index 00000000..2028e4c1 --- /dev/null +++ b/webui/src/components/basic/ab-add.vue @@ -0,0 +1,77 @@ + + + + + diff --git a/webui/src/components/basic/ab-button.stories.ts b/webui/src/components/basic/ab-button.stories.ts new file mode 100644 index 00000000..87fd4e20 --- /dev/null +++ b/webui/src/components/basic/ab-button.stories.ts @@ -0,0 +1,32 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbButton from './ab-button.vue'; + +const meta: Meta = { + title: 'basic/ab-button', + component: AbButton, + tags: ['autodocs'], + argTypes: { + type: { + control: { type: 'select' }, + options: ['primary', 'warn'], + }, + size: { + control: { type: 'select' }, + options: ['big', 'normal', 'small'], + }, + }, +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbButton }, + setup() { + return { args }; + }, + template: 'button', + }), +}; diff --git a/webui/src/components/basic/ab-button.vue b/webui/src/components/basic/ab-button.vue new file mode 100644 index 00000000..e11a5279 --- /dev/null +++ b/webui/src/components/basic/ab-button.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/webui/src/components/basic/ab-checkbox.stories.ts b/webui/src/components/basic/ab-checkbox.stories.ts new file mode 100644 index 00000000..ccf2eb4d --- /dev/null +++ b/webui/src/components/basic/ab-checkbox.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbCheckbox from './ab-checkbox.vue'; + +const meta: Meta = { + title: 'basic/ab-checkbox', + component: AbCheckbox, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbCheckbox }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-checkbox.vue b/webui/src/components/basic/ab-checkbox.vue new file mode 100644 index 00000000..e787cef4 --- /dev/null +++ b/webui/src/components/basic/ab-checkbox.vue @@ -0,0 +1,48 @@ + + + diff --git a/webui/src/components/basic/ab-page-title.stories.ts b/webui/src/components/basic/ab-page-title.stories.ts new file mode 100644 index 00000000..cfe12778 --- /dev/null +++ b/webui/src/components/basic/ab-page-title.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbPageTitle from './ab-page-title.vue'; + +const meta: Meta = { + title: 'basic/ab-PageTitle', + component: AbPageTitle, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbPageTitle }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-page-title.vue b/webui/src/components/basic/ab-page-title.vue new file mode 100644 index 00000000..8ce36519 --- /dev/null +++ b/webui/src/components/basic/ab-page-title.vue @@ -0,0 +1,17 @@ + + + diff --git a/webui/src/components/basic/ab-search.stories.ts b/webui/src/components/basic/ab-search.stories.ts new file mode 100644 index 00000000..18e4548d --- /dev/null +++ b/webui/src/components/basic/ab-search.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbSearch from './ab-search.vue'; + +const meta: Meta = { + title: 'basic/ab-search', + component: AbSearch, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbSearch }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-search.vue b/webui/src/components/basic/ab-search.vue new file mode 100644 index 00000000..9314fed4 --- /dev/null +++ b/webui/src/components/basic/ab-search.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/webui/src/components/basic/ab-select.stories.ts b/webui/src/components/basic/ab-select.stories.ts new file mode 100644 index 00000000..c5924139 --- /dev/null +++ b/webui/src/components/basic/ab-select.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbSelect from './ab-select.vue'; + +const meta: Meta = { + title: 'basic/ab-select', + component: AbSelect, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbSelect }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-select.vue b/webui/src/components/basic/ab-select.vue new file mode 100644 index 00000000..3dd41574 --- /dev/null +++ b/webui/src/components/basic/ab-select.vue @@ -0,0 +1,112 @@ + + + diff --git a/webui/src/components/basic/ab-status.stories.ts b/webui/src/components/basic/ab-status.stories.ts new file mode 100644 index 00000000..5c3feb5c --- /dev/null +++ b/webui/src/components/basic/ab-status.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbStatus from './ab-status.vue'; + +const meta: Meta = { + title: 'basic/ab-status', + component: AbStatus, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbStatus }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-status.vue b/webui/src/components/basic/ab-status.vue new file mode 100644 index 00000000..4da310c4 --- /dev/null +++ b/webui/src/components/basic/ab-status.vue @@ -0,0 +1,23 @@ + + + diff --git a/webui/src/components/basic/ab-switch.stories.ts b/webui/src/components/basic/ab-switch.stories.ts new file mode 100644 index 00000000..07e27d9b --- /dev/null +++ b/webui/src/components/basic/ab-switch.stories.ts @@ -0,0 +1,22 @@ +import type { Meta, StoryObj } from '@storybook/vue3'; + +import AbSwitch from './ab-switch.vue'; + +const meta: Meta = { + title: 'basic/ab-switch', + component: AbSwitch, + tags: ['autodocs'], +}; + +export default meta; +type Story = StoryObj; + +export const Template: Story = { + render: (args) => ({ + components: { AbSwitch }, + setup() { + return { args }; + }, + template: '', + }), +}; diff --git a/webui/src/components/basic/ab-switch.vue b/webui/src/components/basic/ab-switch.vue new file mode 100644 index 00000000..26110050 --- /dev/null +++ b/webui/src/components/basic/ab-switch.vue @@ -0,0 +1,74 @@ + + + + + diff --git a/webui/src/components/basic/ab-tag.stories.ts b/webui/src/components/basic/ab-tag.stories.ts new file mode 100644 index 00000000..07909b12 --- /dev/null +++ b/webui/src/components/basic/ab-tag.stories.ts @@ -0,0 +1,23 @@ +import { Meta, StoryObj} from "@storybook/vue3"; + +import AbTag from "./ab-tag.vue"; + +const meta: Meta = { + title: "basic/ab-tag", + component: AbTag, + tags: ["autodocs"], +} + +export default meta; +type Story = StoryObj; + + +export const Template: Story = { + render: (args) => ({ + components: { AbTag }, + setup() { + return { args }; + }, + template: '', + }), +}; \ No newline at end of file diff --git a/webui/src/components/basic/ab-tag.vue b/webui/src/components/basic/ab-tag.vue new file mode 100644 index 00000000..76dd9d1c --- /dev/null +++ b/webui/src/components/basic/ab-tag.vue @@ -0,0 +1,96 @@ + + + + + diff --git a/webui/src/components/layout/ab-sidebar.vue b/webui/src/components/layout/ab-sidebar.vue new file mode 100644 index 00000000..ad0489c5 --- /dev/null +++ b/webui/src/components/layout/ab-sidebar.vue @@ -0,0 +1,161 @@ + + + diff --git a/webui/src/components/layout/ab-topbar.vue b/webui/src/components/layout/ab-topbar.vue new file mode 100644 index 00000000..1ed9c44b --- /dev/null +++ b/webui/src/components/layout/ab-topbar.vue @@ -0,0 +1,111 @@ + + + diff --git a/webui/src/components/setting/config-download.vue b/webui/src/components/setting/config-download.vue new file mode 100644 index 00000000..aee897fb --- /dev/null +++ b/webui/src/components/setting/config-download.vue @@ -0,0 +1,77 @@ + + + diff --git a/webui/src/components/setting/config-manage.vue b/webui/src/components/setting/config-manage.vue new file mode 100644 index 00000000..83d69b9e --- /dev/null +++ b/webui/src/components/setting/config-manage.vue @@ -0,0 +1,55 @@ + + + diff --git a/webui/src/components/setting/config-normal.vue b/webui/src/components/setting/config-normal.vue new file mode 100644 index 00000000..57cf2a7d --- /dev/null +++ b/webui/src/components/setting/config-normal.vue @@ -0,0 +1,68 @@ + + + diff --git a/webui/src/components/setting/config-notification.vue b/webui/src/components/setting/config-notification.vue new file mode 100644 index 00000000..506d4048 --- /dev/null +++ b/webui/src/components/setting/config-notification.vue @@ -0,0 +1,64 @@ + + + diff --git a/webui/src/components/setting/config-parser.vue b/webui/src/components/setting/config-parser.vue new file mode 100644 index 00000000..ac9a5acb --- /dev/null +++ b/webui/src/components/setting/config-parser.vue @@ -0,0 +1,54 @@ + + + diff --git a/webui/src/components/setting/config-player.vue b/webui/src/components/setting/config-player.vue new file mode 100644 index 00000000..11894359 --- /dev/null +++ b/webui/src/components/setting/config-player.vue @@ -0,0 +1,23 @@ + + + diff --git a/webui/src/components/setting/config-proxy.vue b/webui/src/components/setting/config-proxy.vue new file mode 100644 index 00000000..9e98b063 --- /dev/null +++ b/webui/src/components/setting/config-proxy.vue @@ -0,0 +1,76 @@ + + + diff --git a/webui/src/hooks/useApi.ts b/webui/src/hooks/useApi.ts new file mode 100644 index 00000000..ad2bfe78 --- /dev/null +++ b/webui/src/hooks/useApi.ts @@ -0,0 +1,60 @@ +type AnyAsyncFuntion = (...args: any[]) => Promise; + +export function useApi< + TError = any, + TApi extends AnyAsyncFuntion = AnyAsyncFuntion, + TData = Awaited> +>( + api: TApi, + options?: { + failRule?: (data: TData) => boolean; + message?: { + success?: string; + fail?: string; + error?: string; + }; + } +) { + const data = ref(); + const isLoading = ref(false); + + const fetchResult = createEventHook(); + const fetchError = createEventHook(); + const fetchFinally = createEventHook(); + const message = useMessage(); + + function execute(...params: Parameters) { + isLoading.value = true; + + api(...params) + .then((res: TData) => { + data.value = res; + fetchResult.trigger(res); + + if (options?.failRule && options.failRule(res)) { + options.message?.fail && message.error(options.message.fail); + } else { + options?.message?.success && message.success(options.message.success); + } + }) + .catch((err: TError) => { + fetchError.trigger(err); + + options?.message?.error && message.error(options.message.error); + }) + .finally(() => { + isLoading.value = false; + fetchFinally.trigger(''); + }); + } + + return { + data, + isLoading, + + execute, + onResult: fetchResult.on, + onError: fetchError.on, + onFinally: fetchFinally.on, + }; +} diff --git a/webui/src/hooks/useAppInfo.ts b/webui/src/hooks/useAppInfo.ts new file mode 100644 index 00000000..6bbba953 --- /dev/null +++ b/webui/src/hooks/useAppInfo.ts @@ -0,0 +1,35 @@ +export const useAppInfo = createSharedComposable(() => { + const { auth } = useAuth(); + const running = ref(false); + const version = ref(''); + + function getStatus() { + const { execute, onResult } = useApi(apiProgram.status); + + onResult((res) => { + running.value = res.status; + version.value = res.version; + }); + + if (auth.value !== '') { + execute(); + } + } + + const { pause: offUpdate, resume: onUpdate } = useIntervalFn( + getStatus, + 3000, + { + immediate: false, + immediateCallback: true, + } + ); + + return { + running, + version, + + onUpdate, + offUpdate, + }; +}); diff --git a/webui/src/hooks/useAuth.ts b/webui/src/hooks/useAuth.ts new file mode 100644 index 00000000..3016b5bb --- /dev/null +++ b/webui/src/hooks/useAuth.ts @@ -0,0 +1,119 @@ +import type { User } from '#/auth'; +import type { ApiError } from '#/api'; + +export const useAuth = createSharedComposable(() => { + const auth = useLocalStorage('auth', ''); + const message = useMessage(); + + const user = reactive({ + username: '', + password: '', + }); + + const isLogin = computed(() => auth.value !== ''); + + function clearUser() { + user.username = ''; + user.password = ''; + } + + function check() { + if (user.username === '') { + message.warning('Please Enter Username!'); + return false; + } + + if (user.password === '') { + message.warning('Please Enter Password!'); + return false; + } + + return true; + } + + function login() { + const { execute, onResult, onError } = useApi(apiAuth.login, { + message: { + success: 'Login Success!', + }, + }); + + onResult((res) => { + auth.value = `${res.token_type} ${res.access_token}`; + clearUser(); + }); + + onError((err) => { + const error = err as ApiError; + + if (error.status === 404) { + message.error('请更新AutoBangumi!'); + } else if (error.status === 401){ + message.error(err.msg_zh); + } + }); + + if (check()) { + execute(user.username, user.password); + } + } + + const { execute: logout, onResult: onLogoutResult } = useApi(apiAuth.logout, { + failRule: (res) => !res, + message: { + success: 'Logout Success!', + fail: 'Logout Failed!', + }, + }); + + onLogoutResult(() => { + clearUser(); + auth.value = ''; + }); + + const { execute: refresh, onResult: onRefreshResult } = useApi( + apiAuth.refresh + ); + + onRefreshResult((res) => { + auth.value = `${res.token_type} ${res.access_token}`; + }); + + function update() { + const { execute, onResult } = useApi(apiAuth.update, { + failRule: (res) => res.message !== 'update success', + message: { + success: 'Update Success!', + fail: 'Update Failed!', + }, + }); + + onResult((res) => { + if (res.message === 'update success') { + auth.value = `${res.token_type} ${res.access_token}`; + clearUser(); + } else { + user.password = ''; + } + }); + + if (check()) { + if (user.password.length < 8) { + message.error('Password must be at least 8 characters long!'); + } else { + execute(user.username, user.password); + } + } + } + + return { + auth, + user, + isLogin, + + login, + logout, + refresh, + update, + }; +}); diff --git a/webui/src/hooks/useMessage.ts b/webui/src/hooks/useMessage.ts new file mode 100644 index 00000000..4087663f --- /dev/null +++ b/webui/src/hooks/useMessage.ts @@ -0,0 +1,6 @@ +import { createDiscreteApi } from 'naive-ui'; + +export const useMessage = createSharedComposable(() => { + const { message } = createDiscreteApi(['message']); + return message; +}); diff --git a/webui/src/hooks/useMyI18n.ts b/webui/src/hooks/useMyI18n.ts new file mode 100644 index 00000000..01e30974 --- /dev/null +++ b/webui/src/hooks/useMyI18n.ts @@ -0,0 +1,37 @@ +import { createI18n } from 'vue-i18n'; +import enUS from '@/i18n/en.json'; +import zhCN from '@/i18n/zh-CN.json'; + +const messages = { + en: enUS, + 'zh-CN': zhCN, +}; + +export const useMyI18n = createSharedComposable(() => { + const lang = useLocalStorage('lang', navigator.language); + + const i18n = createI18n({ + legacy: false, + locale: lang.value, + fallbackLocale: 'en', + messages, + }); + + function changeLocale() { + if (lang.value === 'zh-CN') { + i18n.global.locale.value = 'en'; + lang.value = 'en'; + } else { + i18n.global.locale.value = 'zh-CN'; + lang.value = 'zh-CN'; + } + } + + return { + lang, + i18n, + t: i18n.global.t, + locale: i18n.global.locale, + changeLocale, + }; +}); diff --git a/webui/src/i18n/en.json b/webui/src/i18n/en.json new file mode 100644 index 00000000..6521559a --- /dev/null +++ b/webui/src/i18n/en.json @@ -0,0 +1,147 @@ +{ + "login": { + "title": "Login", + "username": "Username", + "password": "Password", + "login_btn": "Login", + "default": "Default" + }, + "sidebar": { + "title": "Menu", + "homepage": "HomePage", + "player": "Player", + "log": "Log", + "config": "Config", + "logout": "Logout", + "downloader": "Downloader", + "calendar": "Calendar", + "rss": "RSS Manager" + }, + "topbar": { + "start": "Start", + "pause": "Pause", + "restart": "Restart", + "shutdown": "Shutdown", + "reset_rule": "Reset Rule", + "search": { + "placeholder": "Type to search" + }, + "profile": { + "title": "Profile", + "pop_title": "Change Account", + "username": "Username", + "password": "Password", + "update_btn": "Update" + }, + "add": { + "title": "Add RSS", + "rss_link": "RSS Link", + "name": "Name", + "aggregate": "Aggregate RSS", + "parser": "Parser", + "placeholder_link": "Please enter the RSS link", + "placeholder_name": "Optional", + "button": "Add" + } + }, + "homepage": { + "rule": { + "official_title": "Official Title", + "year": "Year", + "season": "Season", + "offset": "Offset", + "exclude": "Exclude", + "enable": "Enable", + "disable": "Disable", + "delete": "Delete", + "apply": "Apply", + "yes_btn": "Yes", + "no_btn": "No", + "enable_hit": "Do you want to enable this rule?", + "delete_hit": "Delete Local File?", + "enable_rule": "Enable Rule", + "edit_rule": "Edit Rule" + } + }, + "rss": { + "title": "RSS Item", + "selectbox": "Select", + "name": "Name", + "url": "Url", + "status": "Status", + "delete": "Delete", + "disable": "Disable", + "enable": "Enable", + }, + "player": { + "hit": "Please set up the media player" + }, + "log": { + "title": "Log", + "reset": "Reset", + "copy": "Copy", + "contact_info": "Contact Infomation", + "go": "Go", + "join": "Join", + "bug_repo": "Bug Report" + }, + "config": { + "normal_set": { + "title": "Normal Setting", + "rss_interval": "Interval Time of Rss", + "rename_interval": "Interval Time of Rename", + "web_port": "WebUI Port", + "debug": "Debug" + }, + "parser_set": { + "title": "Parser Setting", + "enable": "Enable", + "source": "Source", + "token": "Token", + "url": "Custom Url", + "language": "Language", + "type": "Parser Type", + "exclude": "Exclude" + }, + "downloader_set": { + "title": "Downloader Setting", + "type": "Downloader Type", + "host": "Host", + "username": "Username", + "password": "Password", + "path": "Download Path", + "ssl": "SSL" + }, + "manage_set": { + "title": "Manage Setting", + "enable": "Enable", + "method": "Rename Method", + "eps": "EPS complete", + "group_tag": "Add Group Tag", + "delete_bad_torrent": "Delete Bad Torrent" + }, + "notification_set": { + "title": "Notification Setting", + "enable": "Enable", + "type": "Type", + "token": "Token", + "chat_id": "Chat ID" + }, + "proxy_set": { + "title": "Proxy Setting", + "enable": "Enable", + "type": "Proxy Type", + "host": "Host", + "port": "Port", + "username": "Username", + "password": "Password" + }, + "media_player_set": { + "title": "Media Player Setting", + "type": "type", + "url": "url" + }, + "cancel": "Cancel", + "apply": "Apply" + } +} diff --git a/webui/src/i18n/zh-CN.json b/webui/src/i18n/zh-CN.json new file mode 100644 index 00000000..670ebeb7 --- /dev/null +++ b/webui/src/i18n/zh-CN.json @@ -0,0 +1,147 @@ +{ + "login": { + "title": "登录", + "username": "用户名", + "password": "密码", + "login_btn": "登录", + "default": "默认账号密码" + }, + "sidebar": { + "title": "菜单", + "homepage": "主页", + "player": "播放器", + "log": "日志", + "config": "设置", + "logout": "退出", + "calendar": "番剧日历", + "downloader": "下载器", + "rss": "RSS 管理" + }, + "topbar": { + "start": "启动", + "pause": "暂停", + "restart": "重启", + "shutdown": "关闭", + "reset_rule": "重置规则", + "search": { + "placeholder": "输入关键字搜索" + }, + "profile": { + "title": "账户设置", + "pop_title": "修改账户", + "username": "用户名", + "password": "密码", + "update_btn": "更新" + }, + "add": { + "title": "添加 RSS", + "rss_link": "RSS 链接", + "name": "名称", + "aggregate": "聚合 RSS", + "parser": "解析器", + "placeholder_link": "请输入 RSS 链接", + "placeholder_name": "可选", + "button": "添加" + } + }, + "homepage": { + "rule": { + "official_title": "官方名称", + "year": "年份", + "season": "季度", + "offset": "剧集偏移", + "exclude": "排除", + "enable": "启用", + "disable": "禁用", + "delete": "删除", + "apply": "应用", + "yes_btn": "是", + "no_btn": "否", + "enable_hit": "确定启用该规则?", + "delete_hit": "是否删除本地文件?", + "enable_rule": "启用规则", + "edit_rule": "编辑规则" + } + }, + "rss": { + "title": "RSS 条目", + "selectbox": "选择", + "name": "名称", + "url": "Url", + "status": "状态", + "delete": "删除", + "disable": "禁用", + "enable": "启用" + }, + "player": { + "hit": "请设置媒体播放器地址" + }, + "log": { + "title": "日志", + "reset": "重置", + "copy": "复制", + "contact_info": "联系方式", + "go": "访问", + "join": "加入", + "bug_repo": "Bug 反馈" + }, + "config": { + "normal_set": { + "title": "常规设置", + "rss_interval": "RSS 间隔", + "rename_interval": "重命名间隔", + "web_port": "网页端口", + "debug": "调试" + }, + "parser_set": { + "title": "解析设置", + "enable": "启用", + "source": "数据源", + "token": "Token", + "url": "自定义网址", + "language": "语言", + "type": "解析类型", + "exclude": "排除" + }, + "downloader_set": { + "title": "下载设置", + "type": "下载器类型", + "host": "下载器地址", + "username": "用户名", + "password": "密码", + "path": "下载地址", + "ssl": "SSL" + }, + "manage_set": { + "title": "番剧管理设置", + "enable": "启用", + "method": "重命名方式", + "eps": "番剧补全", + "group_tag": "添加组标签", + "delete_bad_torrent": "删除坏种" + }, + "notification_set": { + "title": "通知设置", + "enable": "启用", + "type": "类型", + "token": "Token", + "chat_id": "Chat ID" + }, + "proxy_set": { + "title": "代理设置", + "enable": "启用", + "type": "类型", + "host": "地址", + "port": "端口", + "username": "用户名", + "password": "密码" + }, + "media_player_set": { + "title": "播放器设置", + "type": "类型", + "url": "播放器地址" + }, + "cancel": "取消", + "apply": "应用" + } +} diff --git a/webui/src/main.ts b/webui/src/main.ts new file mode 100644 index 00000000..2d2b0dad --- /dev/null +++ b/webui/src/main.ts @@ -0,0 +1,18 @@ +import {createApp} from 'vue'; +import {createPinia} from 'pinia'; +import {router} from './router'; +import App from './App.vue'; + +import '@unocss/reset/tailwind-compat.css'; +import 'virtual:uno.css'; + +const pinia = createPinia(); +const {i18n} = useMyI18n(); + + + +const app = createApp(App); +app.use(router); +app.use(pinia); +app.use(i18n); +app.mount('#app'); diff --git a/webui/src/pages/index.vue b/webui/src/pages/index.vue new file mode 100644 index 00000000..7ef43097 --- /dev/null +++ b/webui/src/pages/index.vue @@ -0,0 +1,26 @@ + + + diff --git a/webui/src/pages/index/bangumi.vue b/webui/src/pages/index/bangumi.vue new file mode 100644 index 00000000..8dfc1d43 --- /dev/null +++ b/webui/src/pages/index/bangumi.vue @@ -0,0 +1,53 @@ + + + + + diff --git a/webui/src/pages/index/calendar.vue b/webui/src/pages/index/calendar.vue new file mode 100644 index 00000000..c3131ddf --- /dev/null +++ b/webui/src/pages/index/calendar.vue @@ -0,0 +1,9 @@ + + + diff --git a/webui/src/pages/index/config.vue b/webui/src/pages/index/config.vue new file mode 100644 index 00000000..55e6e183 --- /dev/null +++ b/webui/src/pages/index/config.vue @@ -0,0 +1,42 @@ + + + diff --git a/webui/src/pages/index/downloader.vue b/webui/src/pages/index/downloader.vue new file mode 100644 index 00000000..2f1930bc --- /dev/null +++ b/webui/src/pages/index/downloader.vue @@ -0,0 +1,9 @@ + + + diff --git a/webui/src/pages/index/log.vue b/webui/src/pages/index/log.vue new file mode 100644 index 00000000..e833dab1 --- /dev/null +++ b/webui/src/pages/index/log.vue @@ -0,0 +1,111 @@ + + + diff --git a/webui/src/pages/index/player.vue b/webui/src/pages/index/player.vue new file mode 100644 index 00000000..57951233 --- /dev/null +++ b/webui/src/pages/index/player.vue @@ -0,0 +1,29 @@ + + + diff --git a/webui/src/pages/index/rss.vue b/webui/src/pages/index/rss.vue new file mode 100644 index 00000000..0e332185 --- /dev/null +++ b/webui/src/pages/index/rss.vue @@ -0,0 +1,73 @@ + + + + + diff --git a/webui/src/pages/login.vue b/webui/src/pages/login.vue new file mode 100644 index 00000000..5268e287 --- /dev/null +++ b/webui/src/pages/login.vue @@ -0,0 +1,42 @@ + + + diff --git a/webui/src/router/index.ts b/webui/src/router/index.ts new file mode 100644 index 00000000..8a9ff55a --- /dev/null +++ b/webui/src/router/index.ts @@ -0,0 +1,34 @@ +import { createRouter, createWebHashHistory } from 'vue-router/auto'; + +const router = createRouter({ + history: createWebHashHistory(), +}); + +router.beforeEach((to) => { + const { isLogin } = useAuth(); + const { type, url } = storeToRefs(usePlayerStore()); + + if (!isLogin.value && to.path !== '/login') { + return { name: 'Login' }; + } + + if (isLogin.value && to.path === '/login') { + return { name: 'Index' }; + } + + if (type.value === 'jump' && url.value !== '' && to.path === '/player') { + open(url.value); + return false; + } + + watch(isLogin, (val) => { + if (to.path === '/login' && val) { + router.replace({ name: 'Index' }); + } + if (to.path !== '/login' && !val) { + router.replace({ name: 'Login' }); + } + }); +}); + +export { router }; diff --git a/webui/src/store/bangumi.ts b/webui/src/store/bangumi.ts new file mode 100644 index 00000000..d0bd8584 --- /dev/null +++ b/webui/src/store/bangumi.ts @@ -0,0 +1,88 @@ +import type { BangumiRule } from '#/bangumi'; +import { ruleTemplate } from '#/bangumi'; +import type { ApiSuccess } from '#/api'; + +export const useBangumiStore = defineStore('bangumi', () => { + const message = useMessage(); + + const bangumi = ref(); + const editRule = reactive<{ + show: boolean; + item: BangumiRule; + }>({ + show: false, + item: ruleTemplate, + }); + + const { execute: getAll, onResult: onBangumiResult } = useApi( + apiBangumi.getAll + ); + const { execute: updateRule, onResult: onUpdateRuleResult } = useApi( + apiBangumi.updateRule + ); + const { execute: enableRule, onResult: onEnableRuleResult } = useApi( + apiBangumi.enableRule + ); + const { execute: disableRule, onResult: onDisableRuleResult } = useApi( + apiBangumi.disableRule + ); + const { execute: deleteRule, onResult: onDeleteRuleResult } = useApi( + apiBangumi.deleteRule + ); + + onBangumiResult((res) => { + function sort(arr: BangumiRule[]) { + return arr.sort((a, b) => b.id - a.id); + } + + const enabled = sort(res.filter((e) => !e.deleted)); + const disabled = sort(res.filter((e) => e.deleted)); + + bangumi.value = [...enabled, ...disabled]; + }); + + function refresh() { + editRule.show = false; + getAll(); + } + + function actionSuccess(apiRes: ApiSuccess) { + message.success(apiRes.msg_en); + refresh(); + } + onUpdateRuleResult(actionSuccess); + onDisableRuleResult(actionSuccess); + onEnableRuleResult(actionSuccess); + onDeleteRuleResult(actionSuccess); + + function openEditPopup(data: BangumiRule) { + editRule.show = true; + editRule.item = data; + } + + function ruleManage( + type: 'disable' | 'delete', + id: number, + deleteFile: boolean + ) { + if (type === 'disable') { + disableRule(id, deleteFile); + } + if (type === 'delete') { + deleteRule(id, deleteFile); + } + } + + return { + bangumi, + editRule, + + getAll, + updateRule, + enableRule, + disableRule, + deleteRule, + openEditPopup, + ruleManage, + }; +}); diff --git a/webui/src/store/config.ts b/webui/src/store/config.ts new file mode 100644 index 00000000..b3cdbc52 --- /dev/null +++ b/webui/src/store/config.ts @@ -0,0 +1,54 @@ +import { type Config, initConfig } from '#/config'; + +export const useConfigStore = defineStore('config', () => { + const config = ref(initConfig); + + const { execute: getConfig, onResult: onGetConfigRusult } = useApi( + apiConfig.getConfig + ); + + onGetConfigRusult((res) => { + config.value = res; + }); + + const { execute: set, onResult: onSetRusult } = useApi( + apiConfig.updateConfig, + { + failRule: (res) => !res, + message: { + success: 'Apply Success!', + fail: 'Apply Failed!', + }, + } + ); + + /** + * 保持 config 后重启,以应用最新配置 + */ + onSetRusult(() => { + const { restart } = useProgramStore(); + restart(); + }); + + const setConfig = () => { + set(config.value); + }; + + function getSettingGroup(key: Tkey) { + return computed({ + get() { + return config.value[key]; + }, + set(newVal) { + config.value[key] = newVal; + }, + }); + } + + return { + config, + getConfig, + setConfig, + getSettingGroup, + }; +}); diff --git a/webui/src/store/log.ts b/webui/src/store/log.ts new file mode 100644 index 00000000..b1fe8566 --- /dev/null +++ b/webui/src/store/log.ts @@ -0,0 +1,51 @@ +export const useLogStore = defineStore('log', () => { + const log = ref(''); + const { auth } = useAuth(); + const message = useMessage(); + + function get() { + const { execute, onResult } = useApi(apiLog.getLog); + + onResult((value) => { + log.value = value; + }); + + if (auth.value !== '') { + execute(); + } + } + + const { execute: reset, onResult: onClearLogResult } = useApi( + apiLog.clearLog + ); + + onClearLogResult((res) => { + if (res) { + log.value = ''; + } + }); + + const { pause: offUpdate, resume: onUpdate } = useIntervalFn(get, 3000, { + immediate: false, + immediateCallback: true, + }); + + function copy() { + const { copy: copyLog, isSupported } = useClipboard({ source: log }); + if (isSupported) { + copyLog(); + message.success('Copy Success!'); + } else { + message.error('Your browser does not support Clipboard API!'); + } + } + + return { + log, + get, + reset, + onUpdate, + offUpdate, + copy, + }; +}); diff --git a/webui/src/store/player.ts b/webui/src/store/player.ts new file mode 100644 index 00000000..3e403406 --- /dev/null +++ b/webui/src/store/player.ts @@ -0,0 +1,13 @@ +type MediaPlayerType = 'jump' | 'iframe'; + +export const usePlayerStore = defineStore('player', () => { + const types = ref(['jump', 'iframe']); + const type = useLocalStorage('media-player-type', 'jump'); + const url = useLocalStorage('media-player-url', ''); + + return { + types, + type, + url, + }; +}); diff --git a/webui/src/store/program.ts b/webui/src/store/program.ts new file mode 100644 index 00000000..23da96bb --- /dev/null +++ b/webui/src/store/program.ts @@ -0,0 +1,28 @@ +export const useProgramStore = defineStore('program', () => { + function opts(handle: string) { + return { + failRule: (res: boolean) => !res, + message: { + success: `${handle} Success!`, + fail: `${handle} Failed!`, + }, + }; + } + + const { execute: start } = useApi(apiProgram.start, opts('Start')); + const { execute: pause } = useApi(apiProgram.stop, opts('Pause')); + const { execute: shutdown } = useApi(apiProgram.shutdown, opts('Shutdown')); + const { execute: restart } = useApi(apiProgram.restart, opts('Restart')); + const { execute: resetRule } = useApi( + apiBangumi.resetAll, + opts('Reset Rule') + ); + + return { + start, + pause, + shutdown, + restart, + resetRule, + }; +}); diff --git a/webui/src/store/rss.ts b/webui/src/store/rss.ts new file mode 100644 index 00000000..72a2c0ca --- /dev/null +++ b/webui/src/store/rss.ts @@ -0,0 +1,73 @@ +import type {RSS} from '#/rss'; +import type {ApiSuccess} from '#/api'; + +export const useRSSStore = defineStore('rss', () => { + const message = useMessage(); + const rss = ref(); + const selectedRSS = ref([]); + + const {execute: getAll, onResult: onRSSResult} = useApi( + apiRSS.get + ); + const {execute: updateRSS, onResult: onUpdateRSSResult} = useApi( + apiRSS.update + ); + const {execute: disableRSS, onResult: onDisableRSSResult} = useApi( + apiRSS.disableMany + ); + const {execute: deleteRSS, onResult: onDeleteRSSResult} = useApi( + apiRSS.deleteMany + ); + + const {execute: enableRSS, onResult: onEnableRSSResult} = useApi( + apiRSS.enableMany + ); + + + onRSSResult((res) => { + function sort(arr: RSS[]) { + return arr.sort((a, b) => b.id - a.id); + } + + const enabled = sort(res.filter((e) => e.enabled)); + const disabled = sort(res.filter((e) => !e.enabled)); + + rss.value = [...enabled, ...disabled]; + }); + + function refresh() { + getAll(); + } + + function disableSelected() { + disableRSS(selectedRSS.value); + } + + function deleteSelected() { + deleteRSS(selectedRSS.value); + } + + function enableSelected() { + enableRSS(selectedRSS.value); + } + + function actionSuccess(apiRes: ApiSuccess) { + message.success(apiRes.msg_en); + refresh(); + } + + onUpdateRSSResult(actionSuccess); + onDeleteRSSResult(actionSuccess); + onDisableRSSResult(actionSuccess); + onEnableRSSResult(actionSuccess); + + return { + rss, + getAll, + refresh, + selectedRSS, + disableSelected, + deleteSelected, + enableSelected, + }; +}); diff --git a/webui/src/store/search.ts b/webui/src/store/search.ts new file mode 100644 index 00000000..98f1a5fd --- /dev/null +++ b/webui/src/store/search.ts @@ -0,0 +1,81 @@ +import {ref} from 'vue'; +import { + EMPTY, + Subject, + debounceTime, + switchMap, tap, +} from "rxjs"; +import type {BangumiRule, SearchResult} from "#/bangumi"; + + +export function useSearchStore() { + const bangumiList = ref([]); + const inputValue = ref(''); + + const providers = ref(['mikan', 'dmhy', 'nyaa']); + const provider = ref(providers.value[0]); + + const loading = ref(false); + + const input$ = new Subject(); + + watch(inputValue, input => { + input$.next(input); + loading.value = !!input; + }) + + const {execute: getProviders, onResult: onGetProvidersResult} = useApi( + apiSearch.getProvider + ); + + onGetProvidersResult((res) => { + providers.value = res; + }); + + /** + * - 输入中 debounce 600ms 后触发搜索 + * - 按回车或点击搜索 icon 按钮后触发搜索 + * - 切换 provider 源站时触发搜索 + */ + + const bangumiInfo$ = input$.pipe( + debounceTime(600), + // switchMap 把输入 keyword 查询为 bangumiInfo$ 流,多次输入自动取消并停止前一次查询 + switchMap((input: string) => { + // 有输入更新后清理之前的搜索结果 + bangumiList.value = []; + return input + ? apiSearch.get(input, provider.value) + : EMPTY + }), + tap((bangumi: BangumiRule) => { + const result: SearchResult = { + order: bangumiList.value.length + 1, + value: bangumi, + } + bangumiList.value.push(result); + }), + ).subscribe() + + function onSearch() { + input$.next(inputValue.value); + } + + function clearSearch() { + inputValue.value = ''; + bangumiList.value = []; + } + + return { + input$, + bangumiInfo$, + inputValue, + onSearch, + clearSearch, + loading, + provider, + getProviders, + providers, + bangumiList, + }; +} \ No newline at end of file diff --git a/webui/src/style/global.scss b/webui/src/style/global.scss new file mode 100644 index 00000000..d6e29925 --- /dev/null +++ b/webui/src/style/global.scss @@ -0,0 +1,50 @@ +$scrollbar-color: #372a87; + +:root { + --scrollbar-size: 6px; + --scrollbar-color: transparent; + --scrollbar-thumb-color: #{rgba($scrollbar-color, 0.5)}; + --scrollbar-thumb-hover-color: #{rgba($scrollbar-color, 1)}; +} + +::-webkit-scrollbar { + width: var(--scrollbar-size); + height: var(--scrollbar-size); +} + +/* 滚动槽--外层轨道 */ +::-webkit-scrollbar-track { + background: var(--scrollbar-color); +} + +/* 内层轨道(不包含滚动块部分) */ +/* 透明度设置为全透明,使得滚动条背景色为网页颜色 */ +::-webkit-scrollbar-track-piece { + opacity: 0; +} + +/* 滚动条滑块 */ +::-webkit-scrollbar-thumb { + border-radius: calc(var(--scrollbar-size) / 2); + background: var(--scrollbar-thumb-color); + + &:hover { + background: var(--scrollbar-thumb-hover-color); + } +} + +/* 滚动条按钮 */ +::-webkit-scrollbar-button { + display: none; +} + +/* 横向滚动条和纵向滚动条相交处尖角的颜色 */ +::-webkit-scrollbar-corner { + background-color: transparent; +} + +input::-webkit-outer-spin-button, +input::-webkit-inner-spin-button { + -webkit-appearance: none; + margin: 0; +} diff --git a/webui/src/style/mixin.scss b/webui/src/style/mixin.scss new file mode 100644 index 00000000..83714f8d --- /dev/null +++ b/webui/src/style/mixin.scss @@ -0,0 +1,13 @@ +@mixin bg-mouse-event($normal, $hover, $active) { + background: $normal; + transition: background 0.3s; + + &:hover { + background: $hover; + } + + &:active { + transition: none; + background: $active; + } +} diff --git a/webui/src/style/transition.scss b/webui/src/style/transition.scss new file mode 100644 index 00000000..16777bfe --- /dev/null +++ b/webui/src/style/transition.scss @@ -0,0 +1,16 @@ +// transition + +.fade { + &-enter-active, + &-leave-active { + transition: opacity 0.2s ease; + } + + &-enter-from, + &-leave-to { + position: absolute; + opacity: 0; + } +} + +// transition-group diff --git a/webui/src/utils/axios.ts b/webui/src/utils/axios.ts new file mode 100644 index 00000000..9b6a3ad0 --- /dev/null +++ b/webui/src/utils/axios.ts @@ -0,0 +1,54 @@ +import Axios from 'axios'; +import type {ApiError} from "#/api"; + +export const axios = Axios.create(); + +// axios.interceptors.request.use((config) => { +// const { auth } = useAuth(); +// +// // if (auth.value !== '' && config.headers) { +// // config.headers.Authorization = auth.value; +// // } +// +// return config; +// }); + +// axios.defaults.baseURL = '/api/v1'; +axios.defaults.withCredentials = true; + +axios.interceptors.response.use( + (res) => { + return res; + }, + (err) => { + const status = err.response.status as ApiError['status']; + const msg_en = (err.response.data.msg_en ?? '') as ApiError['msg_en']; + const msg_zh = (err.response.data.msg_zh ?? '') as ApiError['msg_zh']; + + const error = { + status, + msg_en, + msg_zh, + }; + + const message = useMessage(); + + /** token 过期 */ + if (error.status === 401) { + const {auth} = useAuth(); + auth.value = ''; + } + + /** 执行失败 */ + if (error.status === 406) { + message.error(error.msg_zh); + } + + if (error.status === 500) { + const msg = (err.response.data.msg_en ?? '') as ApiError['msg_en'] + message.error(msg); + } + + return Promise.reject(error); + } +); diff --git a/webui/src/utils/omit.test.ts b/webui/src/utils/omit.test.ts new file mode 100644 index 00000000..7748deaf --- /dev/null +++ b/webui/src/utils/omit.test.ts @@ -0,0 +1,22 @@ +import { expect, it } from 'vitest'; +import { omit } from './omit'; + +it('test omit', () => { + const obj = { + a: 1, + b: 2, + c: 3, + d: 4, + }; + + expect(omit(obj, ['a'])).toStrictEqual({ + b: 2, + c: 3, + d: 4, + }); + + expect(omit(obj, ['b', 'c'])).toStrictEqual({ + a: 1, + d: 4, + }); +}); diff --git a/webui/src/utils/omit.ts b/webui/src/utils/omit.ts new file mode 100644 index 00000000..63d0b180 --- /dev/null +++ b/webui/src/utils/omit.ts @@ -0,0 +1,12 @@ +export function omit( + obj: T, + omitKeys: Array +) { + return Object.keys(obj).reduce((acc, key) => { + if (omitKeys.includes(key)) { + return acc; + } else { + return { ...acc, [key]: obj[key] }; + } + }, {}); +} diff --git a/webui/tsconfig.json b/webui/tsconfig.json new file mode 100644 index 00000000..71dca94e --- /dev/null +++ b/webui/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "ESNext", + "useDefineForClassFields": true, + "module": "ESNext", + "moduleResolution": "Node", + "strict": true, + "jsx": "preserve", + "sourceMap": true, + "resolveJsonModule": true, + "isolatedModules": true, + "esModuleInterop": true, + "lib": ["ESNext", "DOM"], + "skipLibCheck": true, + "noImplicitAny": false, + "baseUrl": "./", + "types": ["vite-plugin-pwa/client"], + "paths": { + "~/*": ["./*"], + "@/*": ["src/*"], + "#/*": ["types/*"] + } + }, + "include": [ + "src/**/*.ts", + "src/**/*.d.ts", + "src/**/*.tsx", + "src/**/*.vue", + "types/*.ts", + "types/dts/*.d.ts" + ], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/webui/tsconfig.node.json b/webui/tsconfig.node.json new file mode 100644 index 00000000..9d31e2ae --- /dev/null +++ b/webui/tsconfig.node.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "composite": true, + "module": "ESNext", + "moduleResolution": "Node", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/webui/types/api.ts b/webui/types/api.ts new file mode 100644 index 00000000..3d0bde9b --- /dev/null +++ b/webui/types/api.ts @@ -0,0 +1,24 @@ +export type AuthError = 'Not authenticated'; + +export type LoginError = 'Password error' | 'User not found'; + +export type ApiErrorMessage = AuthError | LoginError; + +/** + * 401 Token 过期 + * 404 Not Found + * 406 Not Acceptable + * 500 Internal Server Error + */ +export type StatusCode = 401 | 404 | 406 | 500; + +export interface ApiError { + status: StatusCode; + msg_en: string; + msg_zh: string; +} + +export interface ApiSuccess { + msg_en: string; + msg_zh: string; +} \ No newline at end of file diff --git a/webui/types/auth.ts b/webui/types/auth.ts new file mode 100644 index 00000000..71bb3ba6 --- /dev/null +++ b/webui/types/auth.ts @@ -0,0 +1,18 @@ +export interface LoginSuccess { + access_token: string; + token_type: string; + expire: number; +} + +export interface Logout { + message: 'logout success'; +} + +export interface Update extends LoginSuccess { + message: 'update success'; +} + +export interface User { + username: string; + password: string; +} diff --git a/webui/types/bangumi.ts b/webui/types/bangumi.ts new file mode 100644 index 00000000..b11950bd --- /dev/null +++ b/webui/types/bangumi.ts @@ -0,0 +1,60 @@ +/** + * @type `Bangumi` in backend/src/module/models/bangumi.py + */ +export interface BangumiRule { + added: boolean; + deleted: boolean; + dpi: string; + eps_collect: boolean; + filter: string[]; + group_name: string; + id: number; + official_title: string; + offset: number; + poster_link: string | null; + rss_link: string[]; + rule_name: string; + save_path: string; + season: number; + season_raw: string; + source: string | null; + subtitle: string; + title_raw: string; + year: string | null; +} + + + +export interface BangumiAPI extends Omit { + filter: string; + rss_link: string; +} + +export interface SearchResult { + order: number; + value: BangumiRule; +} + +export type BangumiUpdate = Omit; + +export const ruleTemplate: BangumiRule = { + added: false, + deleted: false, + dpi: '', + eps_collect: false, + filter: [], + group_name: '', + id: 0, + official_title: '', + offset: 0, + poster_link: '', + rss_link: [], + rule_name: '', + save_path: '', + season: 1, + season_raw: '', + source: null, + subtitle: '', + title_raw: '', + year: null, +}; diff --git a/webui/types/components.ts b/webui/types/components.ts new file mode 100644 index 00000000..5f3af19d --- /dev/null +++ b/webui/types/components.ts @@ -0,0 +1,18 @@ +export interface SelectItem { + id: number; + label?: string; + value: string; + disabled?: boolean; +} + +export interface AbSettingProps { + label: string | (() => string); + type: 'input' | 'switch' | 'select' | 'dynamic-tags'; + css?: string; + prop?: any; + bottomLine?: boolean; +} + +export type SettingItem = AbSettingProps & { + configKey: keyof T; +}; diff --git a/webui/types/config.ts b/webui/types/config.ts new file mode 100644 index 00000000..12c19937 --- /dev/null +++ b/webui/types/config.ts @@ -0,0 +1,124 @@ +import type { UnionToTuple } from '#/utils'; + +export interface Config { + program: { + rss_time: number; + rename_time: number; + webui_port: number; + }; + downloader: { + type: 'qbittorrent'; + host: string; + username: string; + password: string; + path: string; + ssl: boolean; + }; + rss_parser: { + enable: boolean; + type: 'mikan'; + token: string; + custom_url: string; + filter: Array; + language: 'zh' | 'en' | 'jp'; + parser_type: 'tmdb' | 'mikan' | 'parser'; + }; + bangumi_manage: { + enable: boolean; + eps_complete: boolean; + rename_method: 'normal' | 'pn' | 'advance' | 'none'; + group_tag: boolean; + remove_bad_torrent: boolean; + }; + log: { + debug_enable: boolean; + }; + proxy: { + enable: boolean; + type: 'http' | 'https' | 'socks5'; + host: string; + port: number; + username: string; + password: string; + }; + notification: { + enable: boolean; + type: 'telegram' | 'server-chan' | 'bark' | 'wecom'; + token: string; + chat_id: string; + }; +} + +export const initConfig: Config = { + program: { + rss_time: 0, + rename_time: 0, + webui_port: 0, + }, + downloader: { + type: 'qbittorrent', + host: '', + username: '', + password: '', + path: '', + ssl: false, + }, + rss_parser: { + enable: true, + type: 'mikan', + token: '', + custom_url: '', + filter: [], + language: 'zh', + parser_type: 'parser', + }, + bangumi_manage: { + enable: true, + eps_complete: true, + rename_method: 'normal', + group_tag: true, + remove_bad_torrent: true, + }, + log: { + debug_enable: false, + }, + proxy: { + enable: false, + type: 'http', + host: '', + port: 0, + username: '', + password: '', + }, + notification: { + enable: false, + type: 'telegram', + token: '', + chat_id: '', + }, +}; + +type getItem = Pick[T]; + +export type Program = getItem<'program'>; +export type Downloader = getItem<'downloader'>; +export type RssParser = getItem<'rss_parser'>; +export type BangumiManage = getItem<'bangumi_manage'>; +export type Log = getItem<'log'>; +export type Proxy = getItem<'proxy'>; +export type Notification = getItem<'notification'>; + +/** 下载方式 */ +export type DownloaderType = UnionToTuple; +/** rss parser 源 */ +export type RssParserType = UnionToTuple; +/** rss parser 方法 */ +export type RssParserMethodType = UnionToTuple; +/** rss parser 语言 */ +export type RssParserLang = UnionToTuple; +/** 重命名方式 */ +export type RenameMethod = UnionToTuple; +/** 代理类型 */ +export type ProxyType = UnionToTuple; +/** 通知类型 */ +export type NotificationType = UnionToTuple; diff --git a/webui/types/dts/auto-imports.d.ts b/webui/types/dts/auto-imports.d.ts new file mode 100644 index 00000000..f68e10ba --- /dev/null +++ b/webui/types/dts/auto-imports.d.ts @@ -0,0 +1,303 @@ +// Generated by 'unplugin-auto-import' +export {} +declare global { + const EffectScope: typeof import('vue')['EffectScope'] + const acceptHMRUpdate: typeof import('pinia')['acceptHMRUpdate'] + const afterAll: typeof import('vitest')['afterAll'] + const afterEach: typeof import('vitest')['afterEach'] + const apiAuth: typeof import('../../src/api/auth')['apiAuth'] + const apiBangumi: typeof import('../../src/api/bangumi')['apiBangumi'] + const apiCheck: typeof import('../../src/api/check')['apiCheck'] + const apiConfig: typeof import('../../src/api/config')['apiConfig'] + const apiDownload: typeof import('../../src/api/download')['apiDownload'] + const apiLog: typeof import('../../src/api/log')['apiLog'] + const apiProgram: typeof import('../../src/api/program')['apiProgram'] + const apiRSS: typeof import('../../src/api/rss')['apiRSS'] + const apiSearch: typeof import('../../src/api/search')['apiSearch'] + const assert: typeof import('vitest')['assert'] + const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] + const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] + const axios: typeof import('../../src/utils/axios')['axios'] + const beforeAll: typeof import('vitest')['beforeAll'] + const beforeEach: typeof import('vitest')['beforeEach'] + const chai: typeof import('vitest')['chai'] + const computed: typeof import('vue')['computed'] + const computedAsync: typeof import('@vueuse/core')['computedAsync'] + const computedEager: typeof import('@vueuse/core')['computedEager'] + const computedInject: typeof import('@vueuse/core')['computedInject'] + const computedWithControl: typeof import('@vueuse/core')['computedWithControl'] + const controlledComputed: typeof import('@vueuse/core')['controlledComputed'] + const controlledRef: typeof import('@vueuse/core')['controlledRef'] + const createApp: typeof import('vue')['createApp'] + const createEventHook: typeof import('@vueuse/core')['createEventHook'] + const createGlobalState: typeof import('@vueuse/core')['createGlobalState'] + const createInjectionState: typeof import('@vueuse/core')['createInjectionState'] + const createPinia: typeof import('pinia')['createPinia'] + const createReactiveFn: typeof import('@vueuse/core')['createReactiveFn'] + const createSharedComposable: typeof import('@vueuse/core')['createSharedComposable'] + const createUnrefFn: typeof import('@vueuse/core')['createUnrefFn'] + const customRef: typeof import('vue')['customRef'] + const debouncedRef: typeof import('@vueuse/core')['debouncedRef'] + const debouncedWatch: typeof import('@vueuse/core')['debouncedWatch'] + const defineAsyncComponent: typeof import('vue')['defineAsyncComponent'] + const defineComponent: typeof import('vue')['defineComponent'] + const defineLoader: typeof import('vue-router/auto')['defineLoader'] + const definePage: typeof import('unplugin-vue-router/runtime')['_definePage'] + const defineStore: typeof import('pinia')['defineStore'] + const describe: typeof import('vitest')['describe'] + const eagerComputed: typeof import('@vueuse/core')['eagerComputed'] + const effectScope: typeof import('vue')['effectScope'] + const expect: typeof import('vitest')['expect'] + const extendRef: typeof import('@vueuse/core')['extendRef'] + const getActivePinia: typeof import('pinia')['getActivePinia'] + const getCurrentInstance: typeof import('vue')['getCurrentInstance'] + const getCurrentScope: typeof import('vue')['getCurrentScope'] + const h: typeof import('vue')['h'] + const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch'] + const inject: typeof import('vue')['inject'] + const isDefined: typeof import('@vueuse/core')['isDefined'] + const isProxy: typeof import('vue')['isProxy'] + const isReactive: typeof import('vue')['isReactive'] + const isReadonly: typeof import('vue')['isReadonly'] + const isRef: typeof import('vue')['isRef'] + const it: typeof import('vitest')['it'] + const logicAnd: typeof import('@vueuse/core')['logicAnd'] + const logicNot: typeof import('@vueuse/core')['logicNot'] + const logicOr: typeof import('@vueuse/core')['logicOr'] + const makeDestructurable: typeof import('@vueuse/core')['makeDestructurable'] + const mapActions: typeof import('pinia')['mapActions'] + const mapGetters: typeof import('pinia')['mapGetters'] + const mapState: typeof import('pinia')['mapState'] + const mapStores: typeof import('pinia')['mapStores'] + const mapWritableState: typeof import('pinia')['mapWritableState'] + const markRaw: typeof import('vue')['markRaw'] + const nextTick: typeof import('vue')['nextTick'] + const omit: typeof import('../../src/utils/omit')['omit'] + const onActivated: typeof import('vue')['onActivated'] + const onBeforeMount: typeof import('vue')['onBeforeMount'] + const onBeforeRouteLeave: typeof import('vue-router/auto')['onBeforeRouteLeave'] + const onBeforeRouteUpdate: typeof import('vue-router/auto')['onBeforeRouteUpdate'] + const onBeforeUnmount: typeof import('vue')['onBeforeUnmount'] + const onBeforeUpdate: typeof import('vue')['onBeforeUpdate'] + const onClickOutside: typeof import('@vueuse/core')['onClickOutside'] + const onDeactivated: typeof import('vue')['onDeactivated'] + const onErrorCaptured: typeof import('vue')['onErrorCaptured'] + const onKeyStroke: typeof import('@vueuse/core')['onKeyStroke'] + const onLongPress: typeof import('@vueuse/core')['onLongPress'] + const onMounted: typeof import('vue')['onMounted'] + const onRenderTracked: typeof import('vue')['onRenderTracked'] + const onRenderTriggered: typeof import('vue')['onRenderTriggered'] + const onScopeDispose: typeof import('vue')['onScopeDispose'] + const onServerPrefetch: typeof import('vue')['onServerPrefetch'] + const onStartTyping: typeof import('@vueuse/core')['onStartTyping'] + const onUnmounted: typeof import('vue')['onUnmounted'] + const onUpdated: typeof import('vue')['onUpdated'] + const pausableWatch: typeof import('@vueuse/core')['pausableWatch'] + const provide: typeof import('vue')['provide'] + const reactify: typeof import('@vueuse/core')['reactify'] + const reactifyObject: typeof import('@vueuse/core')['reactifyObject'] + const reactive: typeof import('vue')['reactive'] + const reactiveComputed: typeof import('@vueuse/core')['reactiveComputed'] + const reactiveOmit: typeof import('@vueuse/core')['reactiveOmit'] + const reactivePick: typeof import('@vueuse/core')['reactivePick'] + const readonly: typeof import('vue')['readonly'] + const ref: typeof import('vue')['ref'] + const refAutoReset: typeof import('@vueuse/core')['refAutoReset'] + const refDebounced: typeof import('@vueuse/core')['refDebounced'] + const refDefault: typeof import('@vueuse/core')['refDefault'] + const refThrottled: typeof import('@vueuse/core')['refThrottled'] + const refWithControl: typeof import('@vueuse/core')['refWithControl'] + const resolveComponent: typeof import('vue')['resolveComponent'] + const resolveRef: typeof import('@vueuse/core')['resolveRef'] + const resolveUnref: typeof import('@vueuse/core')['resolveUnref'] + const setActivePinia: typeof import('pinia')['setActivePinia'] + const setMapStoreSuffix: typeof import('pinia')['setMapStoreSuffix'] + const shallowReactive: typeof import('vue')['shallowReactive'] + const shallowReadonly: typeof import('vue')['shallowReadonly'] + const shallowRef: typeof import('vue')['shallowRef'] + const storeToRefs: typeof import('pinia')['storeToRefs'] + const suite: typeof import('vitest')['suite'] + const syncRef: typeof import('@vueuse/core')['syncRef'] + const syncRefs: typeof import('@vueuse/core')['syncRefs'] + const templateRef: typeof import('@vueuse/core')['templateRef'] + const test: typeof import('vitest')['test'] + const throttledRef: typeof import('@vueuse/core')['throttledRef'] + const throttledWatch: typeof import('@vueuse/core')['throttledWatch'] + const toRaw: typeof import('vue')['toRaw'] + const toReactive: typeof import('@vueuse/core')['toReactive'] + const toRef: typeof import('vue')['toRef'] + const toRefs: typeof import('vue')['toRefs'] + const triggerRef: typeof import('vue')['triggerRef'] + const tryOnBeforeMount: typeof import('@vueuse/core')['tryOnBeforeMount'] + const tryOnBeforeUnmount: typeof import('@vueuse/core')['tryOnBeforeUnmount'] + const tryOnMounted: typeof import('@vueuse/core')['tryOnMounted'] + const tryOnScopeDispose: typeof import('@vueuse/core')['tryOnScopeDispose'] + const tryOnUnmounted: typeof import('@vueuse/core')['tryOnUnmounted'] + const unref: typeof import('vue')['unref'] + const unrefElement: typeof import('@vueuse/core')['unrefElement'] + const until: typeof import('@vueuse/core')['until'] + const useActiveElement: typeof import('@vueuse/core')['useActiveElement'] + const useApi: typeof import('../../src/hooks/useApi')['useApi'] + const useAppInfo: typeof import('../../src/hooks/useAppInfo')['useAppInfo'] + const useAsyncQueue: typeof import('@vueuse/core')['useAsyncQueue'] + const useAsyncState: typeof import('@vueuse/core')['useAsyncState'] + const useAttrs: typeof import('vue')['useAttrs'] + const useAuth: typeof import('../../src/hooks/useAuth')['useAuth'] + const useBangumiStore: typeof import('../../src/store/bangumi')['useBangumiStore'] + const useBase64: typeof import('@vueuse/core')['useBase64'] + const useBattery: typeof import('@vueuse/core')['useBattery'] + const useBluetooth: typeof import('@vueuse/core')['useBluetooth'] + const useBreakpoints: typeof import('@vueuse/core')['useBreakpoints'] + const useBroadcastChannel: typeof import('@vueuse/core')['useBroadcastChannel'] + const useBrowserLocation: typeof import('@vueuse/core')['useBrowserLocation'] + const useCached: typeof import('@vueuse/core')['useCached'] + const useClamp: typeof import('@vueuse/core')['useClamp'] + const useClipboard: typeof import('@vueuse/core')['useClipboard'] + const useColorMode: typeof import('@vueuse/core')['useColorMode'] + const useConfigStore: typeof import('../../src/store/config')['useConfigStore'] + const useConfirmDialog: typeof import('@vueuse/core')['useConfirmDialog'] + const useCounter: typeof import('@vueuse/core')['useCounter'] + const useCssModule: typeof import('vue')['useCssModule'] + const useCssVar: typeof import('@vueuse/core')['useCssVar'] + const useCssVars: typeof import('vue')['useCssVars'] + const useCurrentElement: typeof import('@vueuse/core')['useCurrentElement'] + const useCycleList: typeof import('@vueuse/core')['useCycleList'] + const useDark: typeof import('@vueuse/core')['useDark'] + const useDateFormat: typeof import('@vueuse/core')['useDateFormat'] + const useDebounce: typeof import('@vueuse/core')['useDebounce'] + const useDebounceFn: typeof import('@vueuse/core')['useDebounceFn'] + const useDebouncedRefHistory: typeof import('@vueuse/core')['useDebouncedRefHistory'] + const useDeviceMotion: typeof import('@vueuse/core')['useDeviceMotion'] + const useDeviceOrientation: typeof import('@vueuse/core')['useDeviceOrientation'] + const useDevicePixelRatio: typeof import('@vueuse/core')['useDevicePixelRatio'] + const useDevicesList: typeof import('@vueuse/core')['useDevicesList'] + const useDisplayMedia: typeof import('@vueuse/core')['useDisplayMedia'] + const useDocumentVisibility: typeof import('@vueuse/core')['useDocumentVisibility'] + const useDraggable: typeof import('@vueuse/core')['useDraggable'] + const useDropZone: typeof import('@vueuse/core')['useDropZone'] + const useElementBounding: typeof import('@vueuse/core')['useElementBounding'] + const useElementByPoint: typeof import('@vueuse/core')['useElementByPoint'] + const useElementHover: typeof import('@vueuse/core')['useElementHover'] + const useElementSize: typeof import('@vueuse/core')['useElementSize'] + const useElementVisibility: typeof import('@vueuse/core')['useElementVisibility'] + const useEventBus: typeof import('@vueuse/core')['useEventBus'] + const useEventListener: typeof import('@vueuse/core')['useEventListener'] + const useEventSource: typeof import('@vueuse/core')['useEventSource'] + const useEyeDropper: typeof import('@vueuse/core')['useEyeDropper'] + const useFavicon: typeof import('@vueuse/core')['useFavicon'] + const useFetch: typeof import('@vueuse/core')['useFetch'] + const useFileDialog: typeof import('@vueuse/core')['useFileDialog'] + const useFileSystemAccess: typeof import('@vueuse/core')['useFileSystemAccess'] + const useFocus: typeof import('@vueuse/core')['useFocus'] + const useFocusWithin: typeof import('@vueuse/core')['useFocusWithin'] + const useFps: typeof import('@vueuse/core')['useFps'] + const useFullscreen: typeof import('@vueuse/core')['useFullscreen'] + const useGamepad: typeof import('@vueuse/core')['useGamepad'] + const useGeolocation: typeof import('@vueuse/core')['useGeolocation'] + const useI18n: typeof import('vue-i18n')['useI18n'] + const useIdle: typeof import('@vueuse/core')['useIdle'] + const useImage: typeof import('@vueuse/core')['useImage'] + const useInfiniteScroll: typeof import('@vueuse/core')['useInfiniteScroll'] + const useIntersectionObserver: typeof import('@vueuse/core')['useIntersectionObserver'] + const useInterval: typeof import('@vueuse/core')['useInterval'] + const useIntervalFn: typeof import('@vueuse/core')['useIntervalFn'] + const useKeyModifier: typeof import('@vueuse/core')['useKeyModifier'] + const useLastChanged: typeof import('@vueuse/core')['useLastChanged'] + const useLocalStorage: typeof import('@vueuse/core')['useLocalStorage'] + const useLogStore: typeof import('../../src/store/log')['useLogStore'] + const useMagicKeys: typeof import('@vueuse/core')['useMagicKeys'] + const useManualRefHistory: typeof import('@vueuse/core')['useManualRefHistory'] + const useMediaControls: typeof import('@vueuse/core')['useMediaControls'] + const useMediaQuery: typeof import('@vueuse/core')['useMediaQuery'] + const useMemoize: typeof import('@vueuse/core')['useMemoize'] + const useMemory: typeof import('@vueuse/core')['useMemory'] + const useMessage: typeof import('../../src/hooks/useMessage')['useMessage'] + const useMounted: typeof import('@vueuse/core')['useMounted'] + const useMouse: typeof import('@vueuse/core')['useMouse'] + const useMouseInElement: typeof import('@vueuse/core')['useMouseInElement'] + const useMousePressed: typeof import('@vueuse/core')['useMousePressed'] + const useMutationObserver: typeof import('@vueuse/core')['useMutationObserver'] + const useMyI18n: typeof import('../../src/hooks/useMyI18n')['useMyI18n'] + const useNavigatorLanguage: typeof import('@vueuse/core')['useNavigatorLanguage'] + const useNetwork: typeof import('@vueuse/core')['useNetwork'] + const useNow: typeof import('@vueuse/core')['useNow'] + const useObjectUrl: typeof import('@vueuse/core')['useObjectUrl'] + const useOffsetPagination: typeof import('@vueuse/core')['useOffsetPagination'] + const useOnline: typeof import('@vueuse/core')['useOnline'] + const usePageLeave: typeof import('@vueuse/core')['usePageLeave'] + const useParallax: typeof import('@vueuse/core')['useParallax'] + const usePermission: typeof import('@vueuse/core')['usePermission'] + const usePlayerStore: typeof import('../../src/store/player')['usePlayerStore'] + const usePointer: typeof import('@vueuse/core')['usePointer'] + const usePointerSwipe: typeof import('@vueuse/core')['usePointerSwipe'] + const usePreferredColorScheme: typeof import('@vueuse/core')['usePreferredColorScheme'] + const usePreferredDark: typeof import('@vueuse/core')['usePreferredDark'] + const usePreferredLanguages: typeof import('@vueuse/core')['usePreferredLanguages'] + const useProgramStore: typeof import('../../src/store/program')['useProgramStore'] + const useRSSStore: typeof import('../../src/store/rss')['useRSSStore'] + const useRafFn: typeof import('@vueuse/core')['useRafFn'] + const useRefHistory: typeof import('@vueuse/core')['useRefHistory'] + const useResizeObserver: typeof import('@vueuse/core')['useResizeObserver'] + const useRoute: typeof import('vue-router/auto')['useRoute'] + const useRouter: typeof import('vue-router/auto')['useRouter'] + const useScreenOrientation: typeof import('@vueuse/core')['useScreenOrientation'] + const useScreenSafeArea: typeof import('@vueuse/core')['useScreenSafeArea'] + const useScriptTag: typeof import('@vueuse/core')['useScriptTag'] + const useScroll: typeof import('@vueuse/core')['useScroll'] + const useScrollLock: typeof import('@vueuse/core')['useScrollLock'] + const useSearchStore: typeof import('../../src/store/search')['useSearchStore'] + const useSessionStorage: typeof import('@vueuse/core')['useSessionStorage'] + const useShare: typeof import('@vueuse/core')['useShare'] + const useSlots: typeof import('vue')['useSlots'] + const useSpeechRecognition: typeof import('@vueuse/core')['useSpeechRecognition'] + const useSpeechSynthesis: typeof import('@vueuse/core')['useSpeechSynthesis'] + const useStepper: typeof import('@vueuse/core')['useStepper'] + const useStorage: typeof import('@vueuse/core')['useStorage'] + const useStorageAsync: typeof import('@vueuse/core')['useStorageAsync'] + const useStyleTag: typeof import('@vueuse/core')['useStyleTag'] + const useSwipe: typeof import('@vueuse/core')['useSwipe'] + const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList'] + const useTextSelection: typeof import('@vueuse/core')['useTextSelection'] + const useTextareaAutosize: typeof import('@vueuse/core')['useTextareaAutosize'] + const useThrottle: typeof import('@vueuse/core')['useThrottle'] + const useThrottleFn: typeof import('@vueuse/core')['useThrottleFn'] + const useThrottledRefHistory: typeof import('@vueuse/core')['useThrottledRefHistory'] + const useTimeAgo: typeof import('@vueuse/core')['useTimeAgo'] + const useTimeout: typeof import('@vueuse/core')['useTimeout'] + const useTimeoutFn: typeof import('@vueuse/core')['useTimeoutFn'] + const useTimeoutPoll: typeof import('@vueuse/core')['useTimeoutPoll'] + const useTimestamp: typeof import('@vueuse/core')['useTimestamp'] + const useTitle: typeof import('@vueuse/core')['useTitle'] + const useToggle: typeof import('@vueuse/core')['useToggle'] + const useTransition: typeof import('@vueuse/core')['useTransition'] + const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams'] + const useUserMedia: typeof import('@vueuse/core')['useUserMedia'] + const useVModel: typeof import('@vueuse/core')['useVModel'] + const useVModels: typeof import('@vueuse/core')['useVModels'] + const useVibrate: typeof import('@vueuse/core')['useVibrate'] + const useVirtualList: typeof import('@vueuse/core')['useVirtualList'] + const useWakeLock: typeof import('@vueuse/core')['useWakeLock'] + const useWebNotification: typeof import('@vueuse/core')['useWebNotification'] + const useWebSocket: typeof import('@vueuse/core')['useWebSocket'] + const useWebWorker: typeof import('@vueuse/core')['useWebWorker'] + const useWebWorkerFn: typeof import('@vueuse/core')['useWebWorkerFn'] + const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus'] + const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll'] + const useWindowSize: typeof import('@vueuse/core')['useWindowSize'] + const vi: typeof import('vitest')['vi'] + const vitest: typeof import('vitest')['vitest'] + const watch: typeof import('vue')['watch'] + const watchArray: typeof import('@vueuse/core')['watchArray'] + const watchAtMost: typeof import('@vueuse/core')['watchAtMost'] + const watchDebounced: typeof import('@vueuse/core')['watchDebounced'] + const watchEffect: typeof import('vue')['watchEffect'] + const watchIgnorable: typeof import('@vueuse/core')['watchIgnorable'] + const watchOnce: typeof import('@vueuse/core')['watchOnce'] + const watchPausable: typeof import('@vueuse/core')['watchPausable'] + const watchPostEffect: typeof import('vue')['watchPostEffect'] + const watchSyncEffect: typeof import('vue')['watchSyncEffect'] + const watchThrottled: typeof import('@vueuse/core')['watchThrottled'] + const watchTriggerable: typeof import('@vueuse/core')['watchTriggerable'] + const watchWithFilter: typeof import('@vueuse/core')['watchWithFilter'] + const whenever: typeof import('@vueuse/core')['whenever'] +} diff --git a/webui/types/dts/components.d.ts b/webui/types/dts/components.d.ts new file mode 100644 index 00000000..cc313003 --- /dev/null +++ b/webui/types/dts/components.d.ts @@ -0,0 +1,46 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-components +// Read more: https://github.com/vuejs/core/pull/3399 +import '@vue/runtime-core' + +export {} + +declare module '@vue/runtime-core' { + export interface GlobalComponents { + AbAdd: typeof import('./../../src/components/basic/ab-add.vue')['default'] + AbAddRss: typeof import('./../../src/components/ab-add-rss.vue')['default'] + AbBangumiCard: typeof import('./../../src/components/ab-bangumi-card.vue')['default'] + AbButton: typeof import('./../../src/components/basic/ab-button.vue')['default'] + AbChangeAccount: typeof import('./../../src/components/ab-change-account.vue')['default'] + AbCheckbox: typeof import('./../../src/components/basic/ab-checkbox.vue')['default'] + AbContainer: typeof import('./../../src/components/ab-container.vue')['default'] + AbEditRule: typeof import('./../../src/components/ab-edit-rule.vue')['default'] + AbFoldPanel: typeof import('./../../src/components/ab-fold-panel.vue')['default'] + AbLabel: typeof import('./../../src/components/ab-label.vue')['default'] + AbPageTitle: typeof import('./../../src/components/basic/ab-page-title.vue')['default'] + AbPopup: typeof import('./../../src/components/ab-popup.vue')['default'] + AbRssItem: typeof import('./../../src/components/ab-rss-item.vue')['default'] + AbRule: typeof import('./../../src/components/ab-rule.vue')['default'] + AbSearch: typeof import('./../../src/components/basic/ab-search.vue')['default'] + AbSearchBar: typeof import('./../../src/components/ab-search-bar.vue')['default'] + AbSelect: typeof import('./../../src/components/basic/ab-select.vue')['default'] + AbSetting: typeof import('./../../src/components/ab-setting.vue')['default'] + AbSidebar: typeof import('./../../src/components/layout/ab-sidebar.vue')['default'] + AbStatus: typeof import('./../../src/components/basic/ab-status.vue')['default'] + AbStatusBar: typeof import('./../../src/components/ab-status-bar.vue')['default'] + AbSwitch: typeof import('./../../src/components/basic/ab-switch.vue')['default'] + AbTag: typeof import('./../../src/components/basic/ab-tag.vue')['default'] + AbTopbar: typeof import('./../../src/components/layout/ab-topbar.vue')['default'] + ConfigDownload: typeof import('./../../src/components/setting/config-download.vue')['default'] + ConfigManage: typeof import('./../../src/components/setting/config-manage.vue')['default'] + ConfigNormal: typeof import('./../../src/components/setting/config-normal.vue')['default'] + ConfigNotification: typeof import('./../../src/components/setting/config-notification.vue')['default'] + ConfigParser: typeof import('./../../src/components/setting/config-parser.vue')['default'] + ConfigPlayer: typeof import('./../../src/components/setting/config-player.vue')['default'] + ConfigProxy: typeof import('./../../src/components/setting/config-proxy.vue')['default'] + RouterLink: typeof import('vue-router')['RouterLink'] + RouterView: typeof import('vue-router')['RouterView'] + } +} diff --git a/webui/types/dts/html.d.ts b/webui/types/dts/html.d.ts new file mode 100644 index 00000000..ffc45d4e --- /dev/null +++ b/webui/types/dts/html.d.ts @@ -0,0 +1,9 @@ +/** + * https://unocss.dev/presets/attributify#vue-3 + */ + +import type { AttributifyAttributes } from '@unocss/preset-attributify' + +declare module '@vue/runtime-dom' { + interface HTMLAttributes extends AttributifyAttributes {} +} \ No newline at end of file diff --git a/webui/types/dts/router-type.d.ts b/webui/types/dts/router-type.d.ts new file mode 100644 index 00000000..66ba5cf1 --- /dev/null +++ b/webui/types/dts/router-type.d.ts @@ -0,0 +1,149 @@ +/* eslint-disable */ +/* prettier-ignore */ +// @ts-nocheck +// Generated by unplugin-vue-router. ‼️ DO NOT MODIFY THIS FILE ‼️ +// It's recommended to commit this file. +// Make sure to add this file to your tsconfig.json file as an "includes" or "files" entry. + +/// + +import type { + // type safe route locations + RouteLocationTypedList, + RouteLocationResolvedTypedList, + RouteLocationNormalizedTypedList, + RouteLocationNormalizedLoadedTypedList, + RouteLocationAsString, + RouteLocationAsRelativeTypedList, + RouteLocationAsPathTypedList, + + // helper types + // route definitions + RouteRecordInfo, + ParamValue, + ParamValueOneOrMore, + ParamValueZeroOrMore, + ParamValueZeroOrOne, + + // vue-router extensions + _RouterTyped, + RouterLinkTyped, + RouterLinkPropsTyped, + NavigationGuard, + UseLinkFnTyped, + + // data fetching + _DataLoader, + _DefineLoaderOptions, +} from 'unplugin-vue-router/types' + +declare module 'vue-router/auto/routes' { + export interface RouteNamedMap { + 'Index': RouteRecordInfo<'Index', '/', Record, Record>, + 'Bangumi List': RouteRecordInfo<'Bangumi List', '/bangumi', Record, Record>, + 'Calendar': RouteRecordInfo<'Calendar', '/calendar', Record, Record>, + 'Config': RouteRecordInfo<'Config', '/config', Record, Record>, + 'Downloader': RouteRecordInfo<'Downloader', '/downloader', Record, Record>, + 'Log': RouteRecordInfo<'Log', '/log', Record, Record>, + 'Player': RouteRecordInfo<'Player', '/player', Record, Record>, + 'RSS': RouteRecordInfo<'RSS', '/rss', Record, Record>, + 'Login': RouteRecordInfo<'Login', '/login', Record, Record>, + } +} + +declare module 'vue-router/auto' { + import type { RouteNamedMap } from 'vue-router/auto/routes' + + export type RouterTyped = _RouterTyped + + /** + * Type safe version of `RouteLocationNormalized` (the type of `to` and `from` in navigation guards). + * Allows passing the name of the route to be passed as a generic. + */ + export type RouteLocationNormalized = RouteLocationNormalizedTypedList[Name] + + /** + * Type safe version of `RouteLocationNormalizedLoaded` (the return type of `useRoute()`). + * Allows passing the name of the route to be passed as a generic. + */ + export type RouteLocationNormalizedLoaded = RouteLocationNormalizedLoadedTypedList[Name] + + /** + * Type safe version of `RouteLocationResolved` (the returned route of `router.resolve()`). + * Allows passing the name of the route to be passed as a generic. + */ + export type RouteLocationResolved = RouteLocationResolvedTypedList[Name] + + /** + * Type safe version of `RouteLocation` . Allows passing the name of the route to be passed as a generic. + */ + export type RouteLocation = RouteLocationTypedList[Name] + + /** + * Type safe version of `RouteLocationRaw` . Allows passing the name of the route to be passed as a generic. + */ + export type RouteLocationRaw = + | RouteLocationAsString + | RouteLocationAsRelativeTypedList[Name] + | RouteLocationAsPathTypedList[Name] + + /** + * Generate a type safe params for a route location. Requires the name of the route to be passed as a generic. + */ + export type RouteParams = RouteNamedMap[Name]['params'] + /** + * Generate a type safe raw params for a route location. Requires the name of the route to be passed as a generic. + */ + export type RouteParamsRaw = RouteNamedMap[Name]['paramsRaw'] + + export function useRouter(): RouterTyped + export function useRoute(name?: Name): RouteLocationNormalizedLoadedTypedList[Name] + + export const useLink: UseLinkFnTyped + + export function onBeforeRouteLeave(guard: NavigationGuard): void + export function onBeforeRouteUpdate(guard: NavigationGuard): void + + export const RouterLink: RouterLinkTyped + export const RouterLinkProps: RouterLinkPropsTyped + + // Experimental Data Fetching + + export function defineLoader< + P extends Promise, + Name extends keyof RouteNamedMap = keyof RouteNamedMap, + isLazy extends boolean = false, + >( + name: Name, + loader: (route: RouteLocationNormalizedLoaded) => P, + options?: _DefineLoaderOptions, + ): _DataLoader, isLazy> + export function defineLoader< + P extends Promise, + isLazy extends boolean = false, + >( + loader: (route: RouteLocationNormalizedLoaded) => P, + options?: _DefineLoaderOptions, + ): _DataLoader, isLazy> + + export { + _definePage as definePage, + _HasDataLoaderMeta as HasDataLoaderMeta, + _setupDataFetchingGuard as setupDataFetchingGuard, + _stopDataFetchingScope as stopDataFetchingScope, + } from 'unplugin-vue-router/runtime' +} + +declare module 'vue-router' { + import type { RouteNamedMap } from 'vue-router/auto/routes' + + export interface TypesConfig { + beforeRouteUpdate: NavigationGuard + beforeRouteLeave: NavigationGuard + + $route: RouteLocationNormalizedLoadedTypedList[keyof RouteNamedMap] + $router: _RouterTyped + + RouterLink: RouterLinkTyped + } +} diff --git a/webui/types/dts/vite-env.d.ts b/webui/types/dts/vite-env.d.ts new file mode 100644 index 00000000..af36df34 --- /dev/null +++ b/webui/types/dts/vite-env.d.ts @@ -0,0 +1,7 @@ +/// + +declare module '*.vue' { + import type { DefineComponent } from 'vue'; + const component: DefineComponent<{}, {}, any>; + export default component; +} diff --git a/webui/types/rss.ts b/webui/types/rss.ts new file mode 100644 index 00000000..0f20ec9d --- /dev/null +++ b/webui/types/rss.ts @@ -0,0 +1,17 @@ +export interface RSS { + id: number; + name: string; + url: string; + aggregate: boolean; + parser: string; + enabled: boolean; +} + +export const rssTemplate: RSS = { + id: 0, + name: '', + url: '', + aggregate: false, + parser: '', + enabled: false, +}; \ No newline at end of file diff --git a/webui/types/torrent.ts b/webui/types/torrent.ts new file mode 100644 index 00000000..4461727f --- /dev/null +++ b/webui/types/torrent.ts @@ -0,0 +1,7 @@ +export interface Torrent { + id: number; + name: string; + url: string; + homepage: string; + downloaded: boolean; +} \ No newline at end of file diff --git a/webui/types/utils.ts b/webui/types/utils.ts new file mode 100644 index 00000000..c9c2ab8a --- /dev/null +++ b/webui/types/utils.ts @@ -0,0 +1,39 @@ +/** + * 将联合类型转为对应的交叉函数类型 + * @template U 联合类型 + */ +export type UnionToInterFunction = ( + U extends any ? (k: () => U) => void : never +) extends (k: infer I) => void + ? I + : never; + +/** + * 获取联合类型中的最后一个类型 + * @template U 联合类型 + */ +export type GetUnionLast = UnionToInterFunction extends { (): infer A } + ? A + : never; + +/** + * 在元组类型中前置插入一个新的类型(元素); + * @template Tuple 元组类型 + * @template E 新的类型 + */ +export type Prepend = [E, ...Tuple]; + +/** + * 联合类型转元组类型; + * @template Union 联合类型 + * @template T 初始元组类型 + * @template Last 传入联合类型中的最后一个类型(元素),自动生成,内部使用 + */ +export type UnionToTuple< + Union, + T extends any[] = [], + Last = GetUnionLast +> = { + 0: T; + 1: UnionToTuple, Prepend>; +}[[Union] extends [never] ? 0 : 1]; diff --git a/webui/unocss.config.ts b/webui/unocss.config.ts new file mode 100644 index 00000000..2c24c0e7 --- /dev/null +++ b/webui/unocss.config.ts @@ -0,0 +1,83 @@ +import { + defineConfig, + presetAttributify, + presetIcons, + presetUno, +} from 'unocss'; +import presetRemToPx from '@unocss/preset-rem-to-px'; + +export default defineConfig({ + presets: [ + presetUno(), + presetRemToPx(), + presetAttributify(), + presetIcons({ cdn: 'https://esm.sh/' }), + ], + theme: { + colors: { + primary: '#493475', + running: '#A3D491', + stopped: '#DF7F91', + page: '#F0F0F0', + }, + }, + rules: [ + [ + 'bg-theme-row', + { + background: 'linear-gradient(90.5deg, #492897 1.53%, #783674 96.48%)', + }, + ], + [ + 'bg-theme-col', + { + background: 'linear-gradient(180deg, #492897 0%, #783674 100%)', + }, + ], + [ + 'poster-shandow', + { + filter: 'drop-shadow(2px 2px 2px rgba(0, 0, 0, 0.1))', + }, + ], + [ + 'poster-pen-active', + { + background: '#B4ABC6', + 'box-shadow': '2px 2px 4px rgba(0, 0, 0, 0.25)', + }, + ], + ], + shortcuts: [ + [/^wh-(.*)$/, ([, t]) => `w-${t} h-${t}`], + + [ + 'layout-container', + 'wh-screen min-w-1024px min-h-768px p-16px space-y-12px flex flex-col bg-page', + ], + [ + 'layout-main', + 'flex space-x-20px overflow-hidden h-[calc(100vh_-_2_*_16px_-_60px_-_12px)]', + ], + ['layout-content', 'overflow-hidden h-full flex flex-col flex-1'], + + ['rel', 'relative'], + ['abs', 'absolute'], + ['fx-cer', 'flex items-center'], + ['f-cer', 'fx-cer justify-center'], + ['text-h1', 'text-24px'], + ['text-h2', 'text-20px'], + ['text-h3', 'text-16px'], + ['text-main', 'text-12px'], + [ + 'ab-input', + 'outline-none min-w-0 w-200px h-28px px-12px text-main text-right rounded-6px border-1 border-black shadow-inset hover:border-color-[#7A46AE]', + ], + ['input-error', 'border-color-[#CA0E0E]'], + ['is-btn', 'cursor-pointer select-none'], + ['is-disabled', 'cursor-not-allowed select-none'], + ['input-reset', 'bg-transparent min-w-0 flex-1 outline-none'], + ['btn-click', 'hover:scale-110 active:scale-100'], + ['line', 'w-full h-1px bg-[#DFE1EF]'], + ], +}); diff --git a/webui/vite.config.ts b/webui/vite.config.ts new file mode 100644 index 00000000..9dc2a439 --- /dev/null +++ b/webui/vite.config.ts @@ -0,0 +1,108 @@ +import { resolve } from 'node:path'; +import UnoCSS from 'unocss/vite'; +import { defineConfig } from 'vite'; +import vue from '@vitejs/plugin-vue'; +import AutoImport from 'unplugin-auto-import/vite'; +import Components from 'unplugin-vue-components/vite'; +import VueRouter from 'unplugin-vue-router/vite'; +import { VueRouterAutoImports } from 'unplugin-vue-router'; +import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite'; +import { VitePWA } from 'vite-plugin-pwa'; + +// https://vitejs.dev/config/ +export default defineConfig({ + base: './', + plugins: [ + VueRouter({ + dts: 'types/dts/router-type.d.ts', + }), + vue({ + script: { + defineModel: true, + }, + }), + UnoCSS(), + AutoImport({ + imports: [ + 'vue', + 'vitest', + 'pinia', + '@vueuse/core', + VueRouterAutoImports, + 'vue-i18n', + ], + dts: 'types/dts/auto-imports.d.ts', + dirs: ['src/api', 'src/store', 'src/hooks', 'src/utils'], + }), + Components({ + dts: 'types/dts/components.d.ts', + dirs: [ + 'src/components', + 'src/components/basic', + 'src/components/layout', + 'src/components/setting', + ], + }), + VueI18nPlugin({ + include: resolve(__dirname, './src/i18n/**'), + }), + VitePWA({ + injectRegister: false, + registerType: 'autoUpdate', + devOptions: { + enabled: true, + }, + workbox: { + globPatterns: ['**/*.{js,css,html,ico,png,svg}'], + }, + manifest: { + name: 'AutoBangumi', + display: 'standalone', + short_name: 'AutoBangumi', + description: 'Automated Bangumi Download Tool', + theme_color: '#ffffff', + icons: [ + { + src: '/images/logo.svg', + sizes: 'any', + type: 'image/svg+xml', + purpose: 'any', + }, + { + src: '/images/pwa-192.png', + sizes: '192x192', + type: 'image/png', + }, + { + src: '/images/pwa-512.png', + sizes: '512x512', + type: 'image/png', + purpose: 'any', + }, + ], + }, + }), + ], + css: { + preprocessorOptions: { + scss: { + additionalData: '@import "./src/style/mixin.scss";', + }, + }, + }, + build: { + cssCodeSplit: false, + }, + resolve: { + alias: { + '~': resolve(__dirname, './'), + '@': resolve(__dirname, 'src'), + '#': resolve(__dirname, 'types'), + }, + }, + server: { + proxy: { + '^/api/.*': 'http://127.0.0.1:7892', + }, + }, +});