diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 7ef7d028..00000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,46 +0,0 @@
-FROM mcr.microsoft.com/devcontainers/base:jammy
-# FROM mcr.microsoft.com/devcontainers/base:jammy
-
-ARG DEBIAN_FRONTEND=noninteractive
-ARG USER=vscode
-
-RUN DEBIAN_FRONTEND=noninteractive \
- && apt-get update \
- && apt-get install -y build-essential --no-install-recommends make \
- ca-certificates \
- git \
- libssl-dev \
- zlib1g-dev \
- libbz2-dev \
- libreadline-dev \
- libsqlite3-dev \
- wget \
- curl \
- llvm \
- libncurses5-dev \
- xz-utils \
- tk-dev \
- libxml2-dev \
- libxmlsec1-dev \
- libffi-dev \
- liblzma-dev \
- && rm -rf /var/lib/apt/lists/*
-
-# Python and poetry installation
-USER $USER
-ARG HOME="/home/$USER"
-ARG PYTHON_VERSION=3.11
-# ARG PYTHON_VERSION=3.10
-
-ENV PYENV_ROOT="${HOME}/.pyenv"
-ENV PATH="${PYENV_ROOT}/shims:${PYENV_ROOT}/bin:${HOME}/.local/bin:$PATH"
-
-RUN echo "done 0" \
- && curl https://pyenv.run | bash \
- && echo "done 1" \
- && pyenv install ${PYTHON_VERSION} \
- && echo "done 2" \
- && pyenv global ${PYTHON_VERSION} \
- && echo "done 3" \
- && curl -sSL https://install.python-poetry.org | python3 - \
- && poetry config virtualenvs.in-project true
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
deleted file mode 100644
index 08905421..00000000
--- a/.devcontainer/devcontainer.json
+++ /dev/null
@@ -1,65 +0,0 @@
-{
- "name": "poetry3-poetry-pyenv",
- "build": {
- "dockerfile": "Dockerfile"
- },
-
- // đ Features to add to the Dev Container. More info: https://containers.dev/implementors/features.
- // "features": {},
-
- // đ Use 'forwardPorts' to make a list of ports inside the container available locally.
- // "forwardPorts": [],
-
- // đ Use 'postCreateCommand' to run commands after the container is created.
- // "postCreateCommand": "",
-
- // đ Configure tool-specific properties.
- "customizations": {
- "vscode": {
- "extensions": [
- "ms-python.python",
- "njpwerner.autodocstring",
- "ms-azuretools.vscode-docker",
- "github.copilot-labs",
- "github.copilot-nightly",
- "eamodio.gitlens",
- "visualstudioexptteam.intellicode-api-usage-examples",
- "ms-python.isort",
- "ms-vsliveshare.vsliveshare",
- "matangover.mypy",
- "ms-python.vscode-pylance",
- "mgesbert.python-path",
- "zeshuaro.vscode-python-poetry",
- "njqdev.vscode-python-typehint",
- "ms-python.black-formatter"
- ]
- }
- },
- "features": {
- "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {},
- "ghcr.io/devcontainers/features/github-cli:1": {},
- "ghcr.io/devcontainers/features/sshd:1": {},
- "ghcr.io/devcontainers-contrib/features/black:2": {},
- "ghcr.io/devcontainers-contrib/features/curl-apt-get:1": {},
- "ghcr.io/devcontainers-contrib/features/ffmpeg-apt-get:1": {},
- "ghcr.io/devcontainers-contrib/features/micro:1": {},
- "ghcr.io/devcontainers-contrib/features/mosh-apt-get:1": {},
- "ghcr.io/devcontainers-contrib/features/mypy:2": {},
- "ghcr.io/devcontainers-contrib/features/poetry:2": {},
- "ghcr.io/devcontainers-contrib/features/wget-apt-get:1": {},
- "ghcr.io/stuartleeks/dev-container-features/shell-history:0": {},
- "ghcr.io/jckimble/devcontainer-features/ngrok:3": {},
- "ghcr.io/devcontainers/features/common-utils:2": {
- "installZsh": true,
- "configureZshAsDefaultShell": true,
- "installOhMyZsh": true,
- "upgradePackages": true,
- "username": "codespace",
- "userUid": "automatic",
- "userGid": "automatic"
- }
- }
-
- // đ Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
- // "remoteUser": "root"
-}
diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..2d6d258f
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,3 @@
+[*.{kt,kts}]
+ktlint_code_style = intellij_idea
+ktlint_standard_no-wildcard-imports = disabled
\ No newline at end of file
diff --git a/.env.example b/.env.example
new file mode 100644
index 00000000..1b1b56fd
--- /dev/null
+++ b/.env.example
@@ -0,0 +1,15 @@
+# Optional token for API calls to the backend
+BACKEND_API_TOKEN=
+
+# Database connection details
+DB_URL=jdbc:h2:./persistence/revanced-api
+DB_USER=
+DB_PASSWORD=
+
+# Digest auth to issue JWT tokens in the format SHA256("username:ReVanced:password")
+AUTH_SHA256_DIGEST=
+
+# JWT configuration for authenticated API endpoints
+JWT_SECRET=
+JWT_ISSUER=
+JWT_VALIDITY_IN_MIN=
diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 00000000..097f9f98
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,9 @@
+#
+# https://help.github.com/articles/dealing-with-line-endings/
+#
+# Linux start script should use lf
+/gradlew text eol=lf
+
+# These are Windows script files and should use crlf
+*.bat text eol=crlf
+
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 00000000..9cae518e
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,109 @@
+name: đ Bug report
+description: Report a bug or an issue.
+title: 'bug: '
+labels: ['Bug report']
+body:
+ - type: markdown
+ attributes:
+ value: |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Continuing the legacy of Vanced
+
+
+ # ReVanced API bug report
+
+ Before creating a new bug report, please keep the following in mind:
+
+ - **Do not submit a duplicate bug report**: Search for existing bug reports [here](https://github.com/ReVanced/revanced-api/issues?q=label%3A%22Bug+report%22).
+ - **Review the contribution guidelines**: Make sure your bug report adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-api/blob/main/CONTRIBUTING.md).
+ - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
+ - type: textarea
+ attributes:
+ label: Bug description
+ description: |
+ - Describe your bug in detail
+ - Add steps to reproduce the bug if possible (Step 1. ... Step 2. ...)
+ - Add images and videos if possible
+ validations:
+ required: true
+ - type: textarea
+ attributes:
+ label: Error logs
+ description: Exceptions can be captured by running `logcat | grep AndroidRuntime` in a shell.
+ render: shell
+ - type: textarea
+ attributes:
+ label: Solution
+ description: If applicable, add a possible solution to the bug.
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: Add additional context here.
+ - type: checkboxes
+ id: acknowledgements
+ attributes:
+ label: Acknowledgements
+ description: Your bug report will be closed if you don't follow the checklist below.
+ options:
+ - label: I have checked all open and closed bug reports and this is not a duplicate.
+ required: true
+ - label: I have chosen an appropriate title.
+ required: true
+ - label: All requested information has been provided properly.
+ required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 00000000..8bc7f7ee
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,5 @@
+blank_issues_enabled: false
+contact_links:
+ - name: đ¨ Discussions
+ url: https://github.com/revanced/revanced-suggestions/discussions
+ about: Have something unspecific to ReVanced APi in mind? Search for or start a new discussion!
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 00000000..fab7f3fa
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,105 @@
+name: â Feature request
+description: Create a detailed request for a new feature.
+title: 'feat: '
+labels: ['Feature request']
+body:
+ - type: markdown
+ attributes:
+ value: |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Continuing the legacy of Vanced
+
+
+ # ReVanced APi feature request
+
+ Before creating a new feature request, please keep the following in mind:
+
+ - **Do not submit a duplicate feature request**: Search for existing feature requests [here](https://github.com/ReVanced/revanced-api/issues?q=label%3A%22Feature+request%22).
+ - **Review the contribution guidelines**: Make sure your feature request adheres to it. You can find the guidelines [here](https://github.com/ReVanced/revanced-api/blob/main/CONTRIBUTING.md).
+ - **Do not use the issue page for support**: If you need help or have questions, check out other platforms on [revanced.app](https://revanced.app).
+ - type: textarea
+ attributes:
+ label: Feature description
+ description: |
+ - Describe your feature in detail
+ - Add images, videos, links, examples, references, etc. if possible
+ - type: textarea
+ attributes:
+ label: Motivation
+ description: |
+ A strong motivation is necessary for a feature request to be considered.
+
+ - Why should this feature be implemented?
+ - What is the explicit use case?
+ - What are the benefits?
+ - What makes this feature important?
+ validations:
+ required: true
+ - type: checkboxes
+ id: acknowledgements
+ attributes:
+ label: Acknowledgements
+ description: Your feature request will be closed if you don't follow the checklist below.
+ options:
+ - label: I have checked all open and closed feature requests and this is not a duplicate
+ required: true
+ - label: I have chosen an appropriate title.
+ required: true
+ - label: All requested information has been provided properly.
+ required: true
diff --git a/.github/config.yml b/.github/config.yml
new file mode 100644
index 00000000..075f56b5
--- /dev/null
+++ b/.github/config.yml
@@ -0,0 +1,2 @@
+firstPRMergeComment: >
+ Thank you for contributing to ReVanced. Join us on [Discord](https://revanced.app/discord) to receive a role for your contribution.
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
deleted file mode 100644
index f02748cd..00000000
--- a/.github/dependabot.yml
+++ /dev/null
@@ -1,25 +0,0 @@
-version: 2
-updates:
- - package-ecosystem: "github-actions"
- directory: "/"
- schedule:
- interval: "daily"
- target-branch: "dev"
- assignees:
- - "alexandreteles"
-
- - package-ecosystem: "pip"
- directory: "/"
- schedule:
- interval: "daily"
- target-branch: "dev"
- assignees:
- - "alexandreteles"
-
- - package-ecosystem: "docker"
- directory: "/"
- schedule:
- interval: "daily"
- target-branch: "dev"
- assignees:
- - "alexandreteles"
diff --git a/.github/workflows/build_pull_request.yml b/.github/workflows/build_pull_request.yml
new file mode 100644
index 00000000..250871bc
--- /dev/null
+++ b/.github/workflows/build_pull_request.yml
@@ -0,0 +1,25 @@
+name: Build pull request
+
+on:
+ workflow_dispatch:
+ pull_request:
+ branches:
+ - dev
+
+jobs:
+ release:
+ name: Build
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+
+ - name: Cache Gradle
+ uses: burrunan/gradle-cache-action@v1
+
+ - name: Build
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: ./gradlew build --no-daemon
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
deleted file mode 100644
index 5373d7e8..00000000
--- a/.github/workflows/codeql.yml
+++ /dev/null
@@ -1,54 +0,0 @@
-name: "CodeQL"
-
-on:
- push:
- branches: [dev]
- pull_request:
- types: [opened, reopened, edited, synchronize]
- schedule:
- - cron: "29 5 * * 5"
- workflow_dispatch:
-
-jobs:
- analyze:
- name: Analyze
- runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
- timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
- permissions:
- actions: read
- contents: read
- security-events: write
- strategy:
- fail-fast: false
- matrix:
- language: ["python"]
-
- steps:
- - name: Checkout repository
- uses: actions/checkout@v4
-
- - name: Set up Python
- uses: actions/setup-python@v5
- with:
- python-version: "3.11.7"
-
- - name: Install project dependencies
- run: |
- python -m pip install --upgrade pip
- if [ -f requirements.txt ];
- then pip install -r requirements.txt;
- fi
-
- - name: Initialize CodeQL
- uses: github/codeql-action/init@v3
- with:
- languages: ${{ matrix.language }}
- queries: security-and-quality
-
- - name: Autobuild
- uses: github/codeql-action/autobuild@v3
-
- - name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
- with:
- category: "/language:${{matrix.language}}"
diff --git a/.github/workflows/dev.yml b/.github/workflows/dev.yml
deleted file mode 100644
index 91b030c3..00000000
--- a/.github/workflows/dev.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-name: Build dev branch
-
-on:
- push:
- branches: [ "dev" ]
- schedule:
- - cron: '24 9 * * 6'
- workflow_dispatch:
-
-env:
- REGISTRY: ghcr.io
- IMAGE_NAME: ${{ github.repository }}
- IMAGE_TAG: ${{ github.sha }}
-
-jobs:
- security_checks:
- runs-on: ubuntu-latest
- name: Security check
- steps:
- - uses: actions/checkout@v4
- - name: Security Checks (PyCharm Security)
- uses: tonybaloney/pycharm-security@master
- with:
- path: .
-
- build:
- needs: security_checks
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout Dockerfile
- id: checkout
- uses: actions/checkout@v4
- with:
- ref: ${{ inputs.branch }}
-
- - name: Setup QEMU
- id: qemu
- uses: docker/setup-qemu-action@v3
- with:
- image: tonistiigi/binfmt:latest
- platforms: all
-
- - name: Setup Docker Buildx
- id: buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- flavor: |
- latest=${{ startsWith(github.ref, 'refs/heads/main') }}
- suffix=-${{ github.sha }}
-
- - name: Build Docker image
- id: build
- uses: docker/build-push-action@v5
- with:
- context: .
- file: ./Dockerfile
- platforms: linux/amd64,linux/arm64/v8
- push: false
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index 886e0ace..00000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-name: Build and Publish Docker Image
-
-on:
- push:
- branches: [main]
- schedule:
- - cron: "24 9 * * 6"
- workflow_dispatch:
-
-env:
- REGISTRY: ghcr.io
- IMAGE_NAME: ${{ github.repository }}
- IMAGE_TAG: ${{ github.sha }}
-
-jobs:
- build:
- runs-on: ubuntu-latest
- permissions:
- contents: read
- packages: write
-
- steps:
- - name: Checkout Dockerfile
- id: checkout
- uses: actions/checkout@v4
-
- - name: Setup QEMU
- id: qemu
- uses: docker/setup-qemu-action@v3
- with:
- image: tonistiigi/binfmt:latest
- platforms: all
-
- - name: Setup Docker Buildx
- id: buildx
- uses: docker/setup-buildx-action@v3
-
- - name: Login to GitHub Container Registry
- id: ghcr
- uses: docker/login-action@v3
- with:
- registry: ${{ env.REGISTRY }}
- username: ${{ github.repository_owner }}
- password: ${{ secrets.GH_TOKEN }}
-
- - name: Extract metadata (tags, labels) for Docker
- id: meta
- uses: docker/metadata-action@v5
- with:
- images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
- flavor: |
- latest=${{ startsWith(github.ref, 'refs/heads/main') }}
- suffix=-${{ github.sha }}
-
- - name: Build and push main Docker image
- id: build
- uses: docker/build-push-action@v5
- with:
- build-args: GH_TOKEN=${{ secrets.GH_TOKEN }}
- context: .
- file: ./Dockerfile
- platforms: linux/amd64,linux/arm64/v8
- cache-to: type=gha,mode=max,ignore-error=true
- cache-from: type=gha
- push: true
- tags: ${{ steps.meta.outputs.tags }}
- labels: ${{ steps.meta.outputs.labels }}
diff --git a/.github/workflows/open_pull_request.yml b/.github/workflows/open_pull_request.yml
new file mode 100644
index 00000000..75b8e67f
--- /dev/null
+++ b/.github/workflows/open_pull_request.yml
@@ -0,0 +1,26 @@
+name: Open a PR to main
+
+on:
+ push:
+ branches:
+ - dev
+ workflow_dispatch:
+
+env:
+ MESSAGE: Merge branch `${{ github.head_ref || github.ref_name }}` to `main`
+
+jobs:
+ pull-request:
+ name: Open pull request
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Open pull request
+ uses: repo-sync/pull-request@v2
+ with:
+ destination_branch: 'main'
+ pr_title: 'chore: ${{ env.MESSAGE }}'
+ pr_body: 'This pull request will ${{ env.MESSAGE }}.'
+ pr_draft: true
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 00000000..df90459c
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,87 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ push:
+ branches:
+ - main
+ - dev
+
+jobs:
+ release:
+ name: Release
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ packages: write
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ # Make sure the release step uses its own credentials:
+ # https://github.com/cycjimmy/semantic-release-action#private-packages
+ persist-credentials: false
+ fetch-depth: 0
+
+ - name: Cache Gradle
+ uses: burrunan/gradle-cache-action@v1
+
+ - name: Build
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: ./gradlew startShadowScripts clean
+
+ - name: Setup Node.js
+ uses: actions/setup-node@v4
+ with:
+ node-version: "lts/*"
+ cache: "npm"
+
+ - name: Install dependencies
+ run: npm install
+
+ - name: Import GPG key
+ uses: crazy-max/ghaction-import-gpg@v6
+ with:
+ gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
+ passphrase: ${{ secrets.GPG_PASSPHRASE }}
+ fingerprint: ${{ vars.GPG_FINGERPRINT }}
+
+ - name: Setup QEMU
+ uses: docker/setup-qemu-action@v3
+ with:
+ platforms: amd64, arm64
+
+ - name: Setup Docker Buildx
+ uses: docker/setup-buildx-action@v3
+
+ - name: Release
+ env:
+ DOCKER_REGISTRY_USER: ${{ github.actor }}
+ DOCKER_REGISTRY_PASSWORD: ${{ secrets.GITHUB_TOKEN }}
+ GITHUB_ACTOR: ${{ github.actor }}
+ GITHUB_TOKEN: ${{ secrets.REPOSITORY_PUSH_ACCESS }}
+ run: npm exec semantic-release
+
+ - name: Set Portainer stack webhook URL based on branch
+ run: |
+ if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
+ PORTAINER_WEBHOOK_URL=${{ secrets.PORTAINER_WEBHOOK_MAIN_URL }}
+ else
+ PORTAINER_WEBHOOK_URL=${{ secrets.PORTAINER_WEBHOOK_DEV_URL }}
+ fi
+ echo "PORTAINER_WEBHOOK_URL=$PORTAINER_WEBHOOK_URL" >> $GITHUB_ENV
+
+ - name: Trigger Portainer stack update
+ uses: newarifrh/portainer-service-webhook@v1
+ with:
+ webhook_url: ${{ env.PORTAINER_WEBHOOK_URL }}
+
+ - name: Purge outdated images
+ uses: actions/delete-package-versions@v5
+ with:
+ package-name: 'revanced-api'
+ package-type: 'container'
+ min-versions-to-keep: 5
+ delete-only-untagged-versions: 'true'
+ token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.gitignore b/.gitignore
index b8beef64..674971bb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,164 +1,45 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
+.gradle
build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-wheels/
-share/python-wheels/
-*.egg-info/
-.installed.cfg
-*.egg
-MANIFEST
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.nox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*.cover
-*.py,cover
-.hypothesis/
-.pytest_cache/
-cover/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-local_settings.py
-db.sqlite3
-db.sqlite3-journal
-
-# Flask stuff:
-instance/
-.webassets-cache
-
-# Scrapy stuff:
-.scrapy
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-.pybuilder/
-target/
-
-# Jupyter Notebook
-.ipynb_checkpoints
-
-# IPython
-profile_default/
-ipython_config.py
-
-# pyenv
-# For a library or package, you might want to ignore these files since the code is
-# intended to run in multiple environments; otherwise, check them in:
-# .python-version
-
-# pipenv
-# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
-# However, in case of collaboration, if having platform-specific dependencies or dependencies
-# having no cross-platform support, pipenv may install dependencies that don't work, or not
-# install all needed dependencies.
-#Pipfile.lock
-
-# poetry
-# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
-# This is especially recommended for binary packages to ensure reproducibility, and is more
-# commonly ignored for libraries.
-# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
-#poetry.lock
-
-# pdm
-# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
-#pdm.lock
-# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
-# in version control.
-# https://pdm.fming.dev/#use-with-ide
-.pdm.toml
-
-# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
-__pypackages__/
-
-# Celery stuff
-celerybeat-schedule
-celerybeat.pid
-
-# SageMath parsed files
-*.sage.py
-
-# Environments
+!gradle/wrapper/gradle-wrapper.jar
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+bin/
+!**/src/main/**/bin/
+!**/src/test/**/bin/
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+out/
+!**/src/main/**/out/
+!**/src/test/**/out/
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+
+### VS Code ###
+.vscode/
+
+### Project ###
.env
-.venv
-env/
-venv/
-ENV/
-env.bak/
-venv.bak/
-
-# Spyder project settings
-.spyderproject
-.spyproject
-
-# Rope project settings
-.ropeproject
-
-# mkdocs documentation
-/site
-
-# mypy
-.mypy_cache/
-.dmypy.json
-dmypy.json
-
-# Pyre type checker
-.pyre/
-
-# pytype static type analyzer
-.pytype/
-
-# Cython debug symbols
-cython_debug/
-
-# PyCharm
-# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
-# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
-# and can be added to the global gitignore or merged into this file. For a more nuclear
-# option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/
-
-# custom
-env.sh
-persistence/database.db
+persistence/
+configuration.toml
+docker-compose.yml
+patches-public-key.asc
+integrations-public-key.asc
+node_modules/
\ No newline at end of file
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 0412b790..00000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-repos:
- - repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.5.0
- hooks:
- - id: trailing-whitespace
- - id: end-of-file-fixer
- - id: check-yaml
- - id: check-added-large-files
- - id: check-docstring-first
- - id: debug-statements
- - id: requirements-txt-fixer
- - id: check-toml
- - id: check-merge-conflict
- - repo: https://github.com/psf/black
- rev: 23.12.1
- hooks:
- - id: black
- language_version: python3.11
-ci:
- autoupdate_branch: "dev"
diff --git a/.releaserc b/.releaserc
new file mode 100644
index 00000000..21eddf46
--- /dev/null
+++ b/.releaserc
@@ -0,0 +1,70 @@
+{
+ "branches": [
+ "main",
+ {
+ "name": "dev",
+ "prerelease": true
+ }
+ ],
+ "plugins": [
+ [
+ "@semantic-release/commit-analyzer", {
+ "releaseRules": [
+ { "type": "build", "scope": "Needs bump", "release": "patch" }
+ ]
+ }
+ ],
+ "@semantic-release/release-notes-generator",
+ "@semantic-release/changelog",
+ "gradle-semantic-release-plugin",
+ [
+ "@semantic-release/git",
+ {
+ "assets": [
+ "README.md",
+ "CHANGELOG.md",
+ "gradle.properties"
+ ]
+ }
+ ],
+ [
+ "@semantic-release/github",
+ {
+ "assets": [
+ {
+ "path": "build/libs/*"
+ }
+ ],
+ "successComment": false
+ }
+ ],
+ [
+ "@codedependant/semantic-release-docker",
+ {
+ "dockerImage": "revanced-api",
+ "dockerTags": [
+ "{{#if prerelease.[0]}}dev{{else}}main{{/if}}",
+ "{{#unless prerelease.[0]}}latest{{/unless}}",
+ "{{version}}"
+ ],
+ "dockerRegistry": "ghcr.io",
+ "dockerProject": "revanced",
+ "dockerPlatform": [
+ "linux/amd64",
+ "linux/arm64"
+ ],
+ "dockerArgs": {
+ "GITHUB_ACTOR": null,
+ "GITHUB_TOKEN": null,
+ }
+ }
+ ],
+ [
+ "@saithodev/semantic-release-backmerge",
+ {
+ "backmergeBranches": [{"from": "main", "to": "dev"}],
+ "clearWorkspace": true
+ }
+ ]
+ ]
+}
\ No newline at end of file
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index ad9bb995..00000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "python.analysis.typeCheckingMode": "off",
- "spellright.language": [
- "pt"
- ],
- "spellright.documentTypes": [
- "markdown",
- "latex"
- ]
-}
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 00000000..1fa9448e
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,134 @@
+# [1.0.0-dev.7](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.6...v1.0.0-dev.7) (2024-07-13)
+
+
+### Bug Fixes
+
+* Fix OpenAPI docs casing of a word ([541783d](https://github.com/ReVanced/revanced-api/commit/541783d9599c257f184d1b244e1b857b7c200227))
+
+# [1.0.0-dev.6](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.5...v1.0.0-dev.6) (2024-07-13)
+
+
+### Features
+
+* Add bio field for team members ([c40d50c](https://github.com/ReVanced/revanced-api/commit/c40d50c01368cb6b9ab06857694ec51d27aba2cb))
+
+# [1.0.0-dev.5](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.4...v1.0.0-dev.5) (2024-07-12)
+
+
+### Bug Fixes
+
+* Move robots.txt to root ([2ade550](https://github.com/ReVanced/revanced-api/commit/2ade550d58c0e4b53fa7417bef0064f4f476aed8))
+* Only list public members ([97a5d11](https://github.com/ReVanced/revanced-api/commit/97a5d119ec415f9c25fbc50cb240603047defc73))
+
+
+### Features
+
+* Add configuration to specify public key id ([ad7d4b2](https://github.com/ReVanced/revanced-api/commit/ad7d4b226f71fd965421dc2f2a51825c8e8b3036))
+* Add manager route ([f814fe5](https://github.com/ReVanced/revanced-api/commit/f814fe5825eb8b864f2b0cba53ff721eba577eb4))
+
+# [1.0.0-dev.4](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.3...v1.0.0-dev.4) (2024-07-11)
+
+
+### Features
+
+* List more repository contributors ([19ebc82](https://github.com/ReVanced/revanced-api/commit/19ebc827bfb54a597dd06f9d99bdc820ee9977ee))
+
+# [1.0.0-dev.3](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.2...v1.0.0-dev.3) (2024-07-11)
+
+
+### Bug Fixes
+
+* Move old API endpoint configuration from env to configuration file ([7e99e49](https://github.com/ReVanced/revanced-api/commit/7e99e49af202c4ec0a0d7e61dd0182dd2097e867))
+
+# [1.0.0-dev.2](https://github.com/ReVanced/revanced-api/compare/v1.0.0-dev.1...v1.0.0-dev.2) (2024-07-11)
+
+
+### Bug Fixes
+
+* Configure CORS correctly ([2ed4cf3](https://github.com/ReVanced/revanced-api/commit/2ed4cf3b40caeb6181d068d411344e6732000f22))
+
+# 1.0.0-dev.1 (2024-07-10)
+
+
+### Bug Fixes
+
+* Add missing auth realm ([a6008a2](https://github.com/ReVanced/revanced-api/commit/a6008a2fb6d01fb577dcf357a1d698b6c1068b31))
+* Add missing OpenAPI docs ([d4ac471](https://github.com/ReVanced/revanced-api/commit/d4ac47194e51b3e708516150d1690a72830ab809))
+* add required headers ([#8](https://github.com/ReVanced/revanced-api/issues/8)) ([f4c10dc](https://github.com/ReVanced/revanced-api/commit/f4c10dc064c4ac0fb6b8e612d680e4f6bda2b0c7))
+* Add uri to rate limiter request key ([e8c2488](https://github.com/ReVanced/revanced-api/commit/e8c2488bc61793345c4b8171e520fb0127b34643))
+* **ci:** add git dep ([d61ddcc](https://github.com/ReVanced/revanced-api/commit/d61ddcc8ac76d78b7a79c09bbfba812f652aa4cf))
+* **ci:** fix git deps ([5564c2d](https://github.com/ReVanced/revanced-api/commit/5564c2da0946d67abab0f95e43fe6e6b108f5ec7))
+* Correct env var comment ([9d7b049](https://github.com/ReVanced/revanced-api/commit/9d7b0493498bbf594928fc61181beadf6f59643b))
+* Correct persistence directory name ([6238e33](https://github.com/ReVanced/revanced-api/commit/6238e33c42216885d5e9e8075bfc46eaf2a990ed))
+* **deps:** fix requirements file ([5f0ab26](https://github.com/ReVanced/revanced-api/commit/5f0ab26cedef27cc95eec58ea4dce00904b53289))
+* **deps:** missing pydantic ([089f29e](https://github.com/ReVanced/revanced-api/commit/089f29e95fc6b87f90885eb31b8e3460857224a8))
+* **deps:** update poetry.lock ([b2c2fa7](https://github.com/ReVanced/revanced-api/commit/b2c2fa7136f6305703ba11d0bd5a87c0d563eaf3))
+* Don't configure server ([280dbc3](https://github.com/ReVanced/revanced-api/commit/280dbc30f607483adad0bde6ab1b016d5da047ba))
+* Encode defaults to fix OpenAPI spec ([e9d1c8f](https://github.com/ReVanced/revanced-api/commit/e9d1c8fae0bc46e761056197658c4bb045784104))
+* Finish DB Model to API model transformation inside transaction ([89a577e](https://github.com/ReVanced/revanced-api/commit/89a577e91abbfcd2865e770088661eac4aeb4dd7))
+* fix codeql issues ([b5568db](https://github.com/ReVanced/revanced-api/commit/b5568db79fa0620d06d6945b42a66744b6340bc5))
+* Fix spelling mistake ([17ecf58](https://github.com/ReVanced/revanced-api/commit/17ecf58e550d13dd93ab69e1cf522366aeb3da3f))
+* Increase pool size to mitigate overflow ([#113](https://github.com/ReVanced/revanced-api/issues/113)) ([5aed3d6](https://github.com/ReVanced/revanced-api/commit/5aed3d6ce6efcaf04b3cfa8f344623413518c9b1))
+* Remove punctuation ([f9cae1e](https://github.com/ReVanced/revanced-api/commit/f9cae1ea56c93aded25159f6b0814bf84d192192))
+* remove revanced-api from tools map ([4800ee9](https://github.com/ReVanced/revanced-api/commit/4800ee96a82c0a9fc1905c6960cd560b55304944))
+* Serialize response correctly ([1dccfd2](https://github.com/ReVanced/revanced-api/commit/1dccfd2deff3c5de6a6cf2156cac8516b40bdd22))
+* Set body for all eligible request methods ([c6cacef](https://github.com/ReVanced/revanced-api/commit/c6cacef907a5039ed029e1e26204aaba8e698aaa))
+* unversioned endpoints placement under v0 should be at root ([8b29f49](https://github.com/ReVanced/revanced-api/commit/8b29f49805d4a651bdd26aa4958a3639760a2f4b))
+* Use correct persistance folder path ([500a589](https://github.com/ReVanced/revanced-api/commit/500a5896e34f6a9600dcec2834b3d340161bb90a))
+* Use correct proxy path ([ef92768](https://github.com/ReVanced/revanced-api/commit/ef927688a377c16fe37b578ea870207871c30056))
+* Use correct resource path ([4dffd32](https://github.com/ReVanced/revanced-api/commit/4dffd32c99a5a3deafe21bc9e9960795ff93ff1d))
+* Use multidict 6.0.5, add setup tools as dev dependency ([af19446](https://github.com/ReVanced/revanced-api/commit/af19446a67445e96624dfdb9f1fa6b4de77545c8))
+
+
+### Features
+
+* Add `/list` route ([6c930ff](https://github.com/ReVanced/revanced-api/commit/6c930fff9a99f9ee23edd3d661694d2074f53b23))
+* Add `preferred` field to socials ([#100](https://github.com/ReVanced/revanced-api/issues/100)) ([24c8f60](https://github.com/ReVanced/revanced-api/commit/24c8f60a707ebec9465d9fdcd234b1c949a11a60))
+* Add announcements API ([42f7318](https://github.com/ReVanced/revanced-api/commit/42f731854d0b91070bd7b075054d67d3d9e1d1b4))
+* Add announcements endpoints ([#91](https://github.com/ReVanced/revanced-api/issues/91)) ([8583e2a](https://github.com/ReVanced/revanced-api/commit/8583e2a2bbdd62c4c10eb2af607f0bf6b686331c))
+* Add backend rate limit route ([b967170](https://github.com/ReVanced/revanced-api/commit/b9671703be9f0842c00c38caa0953a177dc74491))
+* Add CLI ([a988ffb](https://github.com/ReVanced/revanced-api/commit/a988ffbd2303a79ee18be7263ef6cd45c7bc4daf))
+* add download_count to releases ([#118](https://github.com/ReVanced/revanced-api/issues/118)) ([665b913](https://github.com/ReVanced/revanced-api/commit/665b913c04edd8e55e7ba89839c5c39f8dfa42ac))
+* add friendly crypto names ([#53](https://github.com/ReVanced/revanced-api/issues/53)) ([7b70780](https://github.com/ReVanced/revanced-api/commit/7b707807cc307c1a64abbb09983fb70d5b095698))
+* Add GPG key to team members ([71f58cf](https://github.com/ReVanced/revanced-api/commit/71f58cf352e06b8504e00582e0c68aec55c4688b))
+* Add local ReVanced API server ([cd5d57f](https://github.com/ReVanced/revanced-api/commit/cd5d57f8f87125df361e23715eda6e755203d727))
+* add member gpg keys ([80cdb3b](https://github.com/ReVanced/revanced-api/commit/80cdb3be6ad2264977bf84269b09546a744576f5))
+* Add OpenAPI docs and cache to routes ([6ea63be](https://github.com/ReVanced/revanced-api/commit/6ea63be490e7786c6486ee78c1fa38f302e8b81c))
+* add preferred field to donations ([#56](https://github.com/ReVanced/revanced-api/issues/56)) ([6b705b1](https://github.com/ReVanced/revanced-api/commit/6b705b10545d5e6d2c9424275fbbd996bc45089f))
+* Add proxy for old API ([39f54bb](https://github.com/ReVanced/revanced-api/commit/39f54bbb32512a6df255bbec6821f7f7acf91340))
+* Add rate limiting to routes ([80403f7](https://github.com/ReVanced/revanced-api/commit/80403f7130cd48e68e802ee3111760256e49c77d))
+* added branding ([#104](https://github.com/ReVanced/revanced-api/issues/104)) ([edcad62](https://github.com/ReVanced/revanced-api/commit/edcad620f29ee7e522bbc3a29db607f9823d9ce9))
+* API Fixes and Adjustments ([#23](https://github.com/ReVanced/revanced-api/issues/23)) ([b18097e](https://github.com/ReVanced/revanced-api/commit/b18097e030c82e97f3880fd0788b562645f6e002))
+* API rewrite ([#2](https://github.com/ReVanced/revanced-api/issues/2)) ([45ef337](https://github.com/ReVanced/revanced-api/commit/45ef33741c7a8fbd0144fda04370fe361a1d7c0c))
+* better versioning engine ([8d36663](https://github.com/ReVanced/revanced-api/commit/8d36663610164d8198c18e5080184c1357f29254))
+* Change default port to avoid using existing port ([9825865](https://github.com/ReVanced/revanced-api/commit/9825865bbc7505fc3e808d21a46a151151796591))
+* Disallow all web crawlers ([#111](https://github.com/ReVanced/revanced-api/issues/111)) ([b69acfa](https://github.com/ReVanced/revanced-api/commit/b69acfa8d7f5385735f933a761239be6afd07384))
+* Do not ignore, if `.env` file is missing ([24c6f4e](https://github.com/ReVanced/revanced-api/commit/24c6f4e4354b4e6da0e4a4e7f0ee0a7a5e3c90ed))
+* favicon ([a8126d7](https://github.com/ReVanced/revanced-api/commit/a8126d785f8f828a746f7f1ce2fe20d1a605e8f8))
+* hostname filtering ([5482d9c](https://github.com/ReVanced/revanced-api/commit/5482d9c44245bae75007935db6ec02fb553bfa2d))
+* Implement more routes and add configuration ([9999b24](https://github.com/ReVanced/revanced-api/commit/9999b242ad05dcea9e6b021e3ed4eeead4567805))
+* Improve routing paths ([df999c0](https://github.com/ReVanced/revanced-api/commit/df999c00c4c1f8645cc67ae19b732f0af9d71823))
+* info endpoint ([#71](https://github.com/ReVanced/revanced-api/issues/71)) ([9bbd056](https://github.com/ReVanced/revanced-api/commit/9bbd056c1bc6a30059a8ed0a47823c228531e4c0))
+* Initialize project ([8ae50b5](https://github.com/ReVanced/revanced-api/commit/8ae50b543eb78f2173c66acc2e9b676a7026f80a))
+* Load system properties ([e373d26](https://github.com/ReVanced/revanced-api/commit/e373d269982428357bd04b659d9d17110cf0d5d2))
+* manager-related endpoints ([3a128c4](https://github.com/ReVanced/revanced-api/commit/3a128c4661b161dc9961837056a3b64b84824162))
+* Move config file to CLI argument ([6a9f0ca](https://github.com/ReVanced/revanced-api/commit/6a9f0cadac9e09bcf834ef708fab180038ebd4bd))
+* **observability:** sentry ([99e645c](https://github.com/ReVanced/revanced-api/commit/99e645c5f5604b5b1c8cbab0bed22177fc01c695))
+* project init ([856fc66](https://github.com/ReVanced/revanced-api/commit/856fc667170d21ae5aba996bcc356ca44412e10d))
+* remove appinfo capabilities ([10f5225](https://github.com/ReVanced/revanced-api/commit/10f5225f514a03b2532ec430b5caace6c6049b92))
+* remove codecov tests ([9c69fa3](https://github.com/ReVanced/revanced-api/commit/9c69fa3b924b2ecda5c52256c383d8619ec61ece))
+* Remove Swagger and OpenAPI ([af0b086](https://github.com/ReVanced/revanced-api/commit/af0b0865f4c2f22975a836b72ff0b902ddac1ce9))
+* Setup CI/CD ([c736a75](https://github.com/ReVanced/revanced-api/commit/c736a75d92d97124e1aca392f37049449a786c84))
+* Setup cors and cache ([205bcde](https://github.com/ReVanced/revanced-api/commit/205bcde77aad90e0eb49fc25961399f1e37698bb))
+* Show default CLI option values ([db0bfc3](https://github.com/ReVanced/revanced-api/commit/db0bfc3be5b8d86466fa7f1a01a72247b4e878aa))
+* Use auth digest instead of basic auth ([89e2acf](https://github.com/ReVanced/revanced-api/commit/89e2acfebb5e14f71d9ce3d962c5531070b7600e))
+* Use Jetty instead of Netty ([c23cd5c](https://github.com/ReVanced/revanced-api/commit/c23cd5cdad01fee52aecdb36b93a619886edfa4d))
+* use objects for /socials and /donations ([#51](https://github.com/ReVanced/revanced-api/issues/51)) ([d4eac5c](https://github.com/ReVanced/revanced-api/commit/d4eac5c757106c4762cb3e95f9e4b3509132b39f))
+* use objects for contact field ([5922830](https://github.com/ReVanced/revanced-api/commit/5922830e0bf1c0504d3205d2fa864c76d0f09c02))
+
+
+### Performance Improvements
+
+* Cache latest announcements for constant access time ([1ca9952](https://github.com/ReVanced/revanced-api/commit/1ca9952de81feeae1333872a7741119d6d8e7814))
+* Cache patches list instead of just the patches file ([7a1957d](https://github.com/ReVanced/revanced-api/commit/7a1957d013cfd0851dc0191b715e8f36c530d9d2))
+* Make async db transactions and use List instead of Set ([a7d1892](https://github.com/ReVanced/revanced-api/commit/a7d1892343094ddb2762ca346759771e6a274081))
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 00000000..6b1aadd6
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Continuing the legacy of Vanced
+
+
+# đ Contribution guidelines
+
+This document describes how to contribute to ReVanced API.
+
+## đ Resources to help you get started
+
+* [Our backlog](https://github.com/orgs/ReVanced/projects/12) is where we keep track of what we're working on
+* [Issues](https://github.com/ReVanced/revanced-api/issues) are where we keep track of bugs and feature requests
+
+## đ Submitting a feature request
+
+Features can be requested by opening an issue using the
+[Feature request issue template](https://github.com/ReVanced/revanced-api/issues/new?assignees=&labels=Feature+request&projects=&template=feature_request.yml&title=feat%3A+).
+
+> **Note**
+> Requests can be accepted or rejected at the discretion of maintainers of ReVanced API.
+> Good motivation has to be provided for a request to be accepted.
+
+## đ Submitting a bug report
+
+If you encounter a bug while using ReVanced API, open an issue using the
+[Bug report issue template](https://github.com/ReVanced/revanced-api/issues/new?assignees=&labels=Bug+report&projects=&template=bug_report.yml&title=bug%3A+).
+
+## đ How to contribute
+
+1. Before contributing, it is recommended to open an issue to discuss your change
+with the maintainers of ReVanced API. This will help you determine whether your change is acceptable
+and whether it is worth your time to implement it
+2. Development happens on the `dev` branch. Fork the repository and create your branch from `dev`
+3. Commit your changes
+4. Submit a pull request to the `dev` branch of the repository and reference issues
+that your pull request closes in the description of your pull request
+5. Our team will review your pull request and provide feedback. Once your pull request is approved,
+it will be merged into the `dev` branch and will be included in the next release of ReVanced API
+
+â¤ī¸ Thank you for considering contributing to ReVanced API,
+ReVanced
diff --git a/Dockerfile b/Dockerfile
index 8c044a72..aa4df89c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,19 +1,19 @@
-FROM python:3.11-slim
+# Build the application
+FROM gradle:latest AS build
+ARG GITHUB_ACTOR
ARG GITHUB_TOKEN
-ARG SENTRY_DSN
-ENV GITHUB_TOKEN $GITHUB_TOKEN
-ENV SENTRY_DSN $SENTRY_DSN
-
-WORKDIR /usr/src/app
+ENV GITHUB_ACTOR=$GITHUB_ACTOR
+ENV GITHUB_TOKEN=$GITHUB_TOKEN
+WORKDIR /app
COPY . .
+RUN gradle startShadowScript --no-daemon
-RUN apt update && \
- apt-get install git build-essential libffi-dev libssl-dev openssl --no-install-recommends -y \
- && pip install --no-cache-dir -r requirements.txt
-
-VOLUME persistence
+# Build the runtime container
+FROM eclipse-temurin:latest
-CMD [ "python3", "-m" , "sanic", "app:app", "--fast", "--access-logs", "--motd", "--noisy-exceptions", "-H", "0.0.0.0"]
+WORKDIR /app
+COPY --from=build /app/build/libs/revanced-api-*.jar revanced-api.jar
+CMD java -jar revanced-api.jar $COMMAND
diff --git a/README.md b/README.md
index aaa86ee8..e520b85d 100644
--- a/README.md
+++ b/README.md
@@ -1,44 +1,165 @@
-# ReVanced Releases API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Continuing the legacy of Vanced
+
+
+# đ ReVanced API
+
+![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/ReVanced/revanced-api/release.yml)
+![AGPLv3 License](https://img.shields.io/badge/License-AGPL%20v3-yellow.svg)
+
+API server for ReVanced.
+
+## â About
+
+ReVanced API is a server that is used as the backend for ReVanced.
+ReVanced API acts as the data source for [ReVanced Website](https://github.com/ReVanced/revanced-website) and powers [ReVanced Manager](https://github.com/ReVanced/revanced-manager)
+with updates and ReVanced Patches.
+
+## đĒ Features
+
+Some of the features ReVanced API include:
+
+- đĸ **Announcements**: Post and get announcements grouped by channels
+- âšī¸ **About**: Get more information such as a description, ways to donate to,
+and links of the hoster of ReVanced API
+- 𧊠**Patches**: Get the latest updates of ReVanced Patches, directly from ReVanced API
+- đĨ **Contributors**: List all contributors involved in the project
+- đ **Backwards compatibility**: Proxy an old API for migration purposes and backwards compatibility
+
+## đ How to get started
+
+ReVanced API can be deployed as a Docker container or used standalone.
+
+## đŗ Docker
+
+To deploy ReVanced API as a Docker container, you can use Docker Compose or Docker CLI.
+The Docker image is published on GitHub Container registry,
+so before you can pull the image, you need to [authenticate to the Container registry](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-container-registry#authenticating-to-the-container-registry).
+
+### đī¸ Docker Compose
+
+1. Create an `.env` file using [.env.example](.env.example) as a template
+2. Create a `configuration.toml` file using [configuration.example.toml](configuration.example.toml) as a template
+3. Create a `docker-compose.yml` file using [docker-compose.example.yml](docker-compose.example.yml) as a template
+4. Run `docker-compose up -d` to start the server
+
+### đģ Docker CLI
+
+1. Create an `.env` file using [.env.example](.env.example) as a template
+2. Create a `configuration.toml` file using [configuration.example.toml](configuration.example.toml) as a template
+3. Start the container using the following command:
+ ```shell
+ docker run -d --name revanced-api \
+ # Mount the .env file
+ -v $(pwd)/.env:/app/.env \
+ # Mount the configuration.toml file
+ -v $(pwd)/configuration.toml:/app/configuration.toml \
+ # Mount the persistence folder
+ -v $(pwd)/persistence:/app/persistence \
+ # Expose the port 8888
+ -p 8888:8888 \
+ # Use the start command to start the server
+ -e COMMAND=start \
+ # Pull the image from the GitHub Container registry
+ ghcr.io/revanced/revanced-api:latest
+ ```
+
+## đĨī¸ Standalone
+
+To deploy ReVanced API standalone, you can either use the pre-built executable or build it from source.
+
+### đĻ Pre-built executable
+
+A Java Runtime Environment (JRE) must be installed.
+
+1. [Download](https://github.com/ReVanced/revanced-api/releases/latest) ReVanced API to a folder
+2. In the same folder, create an `.env` file using [.env.example](.env.example) as a template
+3. In the same folder, create a `configuration.toml` file
+using [configuration.example.toml](configuration.example.toml) as a template
+4. Run `java -jar revanced-api.jar start` to start the server
----
+### đ ī¸ From source
-![License: AGPLv3](https://img.shields.io/github/license/revanced/revanced-api)
-[![Build and Publish Docker Image](https://github.com/revanced/revanced-api/actions/workflows/main.yml/badge.svg)](https://github.com/revanced/revanced-api/actions/workflows/main.yml)
+A Java Development Kit (JDK) and Git must be installed.
----
+1. Run `git clone git@github.com:ReVanced/revanced-api.git` to clone the repository
+2. Copy [.env.example](.env.example) to `.env` and fill in the required values
+3. Copy [configuration.example.toml](configuration.example.toml) to `configuration.toml` and fill in the required values
+4. Run `gradlew run --args=start` to start the server
-This is a simple API that proxies requests needed to feed the ReVanced Manager and website with data.
+## đ Everything else
-## Usage
+### đ Contributing
-To run this API, you need Python 3.11.x. You can install the dependencies with poetry:
+Thank you for considering contributing to ReVanced API. You can find the contribution guidelines [here](CONTRIBUTING.md).
-```shell
-poetry install
-```
+### đ ī¸ Building
-Create the following environment variables:
+To build ReVanced API, a Java Development Kit (JDK) and Git must be installed.
+Follow the steps below to build ReVanced API:
-- `GITHUB_TOKEN` with a valid GitHub token with read access to public repositories
-- `SECRET_KEY` to salt login sessions
-- `USERNAME` & `PASSWORD` to initialize the database with a user to login with to authenticated endpoints
+1. Run `git clone git@github.com:ReVanced/revanced-api.git` to clone the repository
+2. Run `gradlew build` to build the project
-Then, you can run the API in development mode with:
+## đ Licence
-```shell
-poetry run sanic app:app --dev
-```
-
-or in production mode with:
-
-```shell
-poetry run sanic app:app --fast
-```
-
-## Contributing
-
-If you want to contribute to this project, feel free to open a pull request or an issue. We don't do much here, so it's pretty easy to contribute.
-
-## License
-
-This project is licensed under the AGPLv3 License - see the [LICENSE](LICENSE) file for details.
+ReVanced API is licensed under the AGPLv3 licence. Please see the [licence file](LICENSE) for more information.
+[tl;dr](https://www.tldrlegal.com/license/gnu-affero-general-public-license-v3-agpl-3-0) you may copy, distribute and
+modify ReVanced API as long as you track changes/dates in source files.
+Any modifications to ReVanced API must also be made available under the GPL along with build & install instructions.
diff --git a/SECURITY.md b/SECURITY.md
deleted file mode 100644
index a96b0b4e..00000000
--- a/SECURITY.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Security Policy
-
-## Supported Tags
-
-| Tag | ReVanced Version |
-| ------- | ------------------ |
-| latest | latest upstream |
-
-## Reporting a Vulnerability
-
-To report a vulnerability, please open an Issue in our issue tracker here on GitHub.
diff --git a/api/__init__.py b/api/__init__.py
deleted file mode 100644
index 1ce029b7..00000000
--- a/api/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# api/__init__.py
-from sanic import Blueprint
-import importlib
-import pkgutil
-from api.utils.versioning import get_version
-
-# Dynamically import all modules in the 'api' package, excluding subdirectories
-versioned_blueprints: dict[str, list] = {}
-for finder, module_name, ispkg in pkgutil.iter_modules(["api"]):
- if not ispkg:
- # Import the module
- module = importlib.import_module(f"api.{module_name}")
-
- # Add the module's blueprint to the versioned list, if it exists
- if hasattr(module, module_name):
- blueprint = getattr(module, module_name)
- version = get_version(module_name)
- versioned_blueprints.setdefault(version, []).append(blueprint)
-
-# Create Blueprint groups for each version
-api = []
-for version, blueprints in versioned_blueprints.items():
- if version == "old" or version == "v0":
- group = Blueprint.group(*blueprints, url_prefix="/")
- else:
- group = Blueprint.group(*blueprints, version=version, url_prefix="/")
- api.append(group)
diff --git a/api/announcements.py b/api/announcements.py
deleted file mode 100644
index bcdc4c06..00000000
--- a/api/announcements.py
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
-This module provides a blueprint for the announcements endpoint.
-
-Routes:
- - GET /announcements: Get a list of announcements from all channels.
- - GET /announcements/: Get a list of announcement from a channel.
- - GET /announcements/latest: Get the latest announcement.
- - GET /announcements//latest: Get the latest announcement from a channel.
- - POST /announcements/: Create an announcement.
- - DELETE /announcements/: Delete an announcement.
-"""
-
-import os
-import datetime
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-from data.database import Session
-from data.models import AnnouncementDbModel, AttachmentDbModel
-
-import sanic_beskar
-
-from api.models.announcements import AnnouncementResponseModel
-from api.utils.limiter import limiter
-
-announcements: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@announcements.get("/announcements")
-@openapi.definition(
- summary="Get a list of announcements",
- response=[[AnnouncementResponseModel]],
-)
-async def get_announcements(request: Request) -> JSONResponse:
- """
- Retrieve a list of announcements.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing a list of announcements from all channels.
- """
-
- session = Session()
-
- announcements = [
- AnnouncementResponseModel.to_response(announcement)
- for announcement in session.query(AnnouncementDbModel).all()
- ]
-
- session.close()
-
- return json(announcements, status=200)
-
-
-@announcements.get("/announcements/")
-@openapi.definition(
- summary="Get a list of announcements from a channel",
- response=[[AnnouncementResponseModel]],
-)
-async def get_announcements_for_channel(request: Request, channel: str) -> JSONResponse:
- """
- Retrieve a list of announcements from a channel.
-
- **Args:**
- - channel (str): The channel to retrieve announcements from.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing a list of announcements from a channel.
- """
-
- session = Session()
-
- announcements = [
- AnnouncementResponseModel.to_response(announcement)
- for announcement in session.query(AnnouncementDbModel)
- .filter_by(channel=channel)
- .all()
- ]
-
- session.close()
-
- return json(announcements, status=200)
-
-
-@announcements.get("/announcements/latest")
-@openapi.definition(
- summary="Get the latest announcement",
- response=AnnouncementResponseModel,
-)
-async def get_latest_announcement(request: Request) -> JSONResponse:
- """
- Retrieve the latest announcement.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the latest announcement.
- """
-
- session = Session()
-
- announcement = (
- session.query(AnnouncementDbModel)
- .order_by(AnnouncementDbModel.id.desc())
- .first()
- )
-
- if not announcement:
- return json({"error": "No announcement found"}, status=404)
-
- announcement_response = AnnouncementResponseModel.to_response(announcement)
-
- session.close()
-
- return json(announcement_response, status=200)
-
-
-# for specific channel
-
-
-@announcements.get("/announcements//latest")
-@openapi.definition(
- summary="Get the latest announcement from a channel",
- response=AnnouncementResponseModel,
-)
-async def get_latest_announcement_for_channel(
- request: Request, channel: str
-) -> JSONResponse:
- """
- Retrieve the latest announcement from a channel.
-
- **Args:**
- - channel (str): The channel to retrieve the latest announcement from.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the latest announcement from a channel.
- """
-
- session = Session()
-
- announcement = (
- session.query(AnnouncementDbModel)
- .filter_by(channel=channel)
- .order_by(AnnouncementDbModel.id.desc())
- .first()
- )
-
- if not announcement:
- return json({"error": "No announcement found"}, status=404)
-
- announcement_response = AnnouncementResponseModel.to_response(announcement)
-
- session.close()
-
- return json(announcement_response, status=200)
-
-
-@announcements.post("/announcements/")
-@limiter.limit("16 per hour")
-@sanic_beskar.auth_required
-@openapi.definition(
- summary="Create an announcement",
- body=AnnouncementResponseModel,
- response=AnnouncementResponseModel,
-)
-async def post_announcement(request: Request, channel: str) -> JSONResponse:
- """
- Create an announcement.
-
- **Args:**
- - author (str | None): The author of the announcement.
- - title (str): The title of the announcement.
- - content (ContentFields | None): The content of the announcement.
- - channel (str): The channel to create the announcement in.
- - nevel (int | None): The severity of the announcement.
- """
- session = Session()
-
- if not request.json:
- return json({"error": "Missing request body"}, status=400)
-
- content = request.json.get("content", None)
-
- author = request.json.get("author", None)
- title = request.json.get("title")
- message = content["message"] if content and "message" in content else None
- attachments = (
- list(
- map(
- lambda url: AttachmentDbModel(attachment_url=url),
- content["attachments"],
- )
- )
- if content and "attachments" in content
- else []
- )
- level = request.json.get("level", None)
- created_at = datetime.datetime.now()
-
- announcement = AnnouncementDbModel(
- author=author,
- title=title,
- message=message,
- attachments=attachments,
- channel=channel,
- created_at=created_at,
- level=level,
- )
-
- session.add(announcement)
- session.commit()
- session.close()
-
- return json({}, status=200)
-
-
-@announcements.delete("/announcements/")
-@sanic_beskar.auth_required
-@openapi.definition(
- summary="Delete an announcement",
-)
-async def delete_announcement(request: Request, announcement_id: int) -> JSONResponse:
- """
- Delete an announcement.
-
- **Args:**
- - announcement_id (int): The ID of the announcement to delete.
-
- **Exceptions:**
- - 404: Announcement not found.
- """
- session = Session()
-
- announcement = (
- session.query(AnnouncementDbModel).filter_by(id=announcement_id).first()
- )
-
- if not announcement:
- return json({"error": "Announcement not found"}, status=404)
-
- session.delete(announcement)
- session.commit()
- session.close()
-
- return json({}, status=200)
diff --git a/api/backends/__init__.py b/api/backends/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/api/backends/backend.py b/api/backends/backend.py
deleted file mode 100644
index 24dfc63f..00000000
--- a/api/backends/backend.py
+++ /dev/null
@@ -1,91 +0,0 @@
-from abc import abstractmethod
-from typing import Any, Protocol
-
-from api.backends.entities import *
-
-
-class Backend(Protocol):
- """Interface for a generic backend.
-
- Attributes:
- name (str): Name of the backend.
- base_url (str): Base URL of the backend.
-
- Methods:
- list_releases: Retrieve a list of releases.
- get_release_by_tag_name: Retrieve a release by its tag name.
- get_latest_release: Retrieve the latest release.
- get_latest_pre_release: Retrieve the latest pre-release.
- get_release_notes: Retrieve the release notes of a specific release.
- get_contributors: Retrieve the list of contributors.
- get_patches: Retrieve the patches of a specific release.
- """
-
- name: str
- base_url: str
-
- def __init__(self, name: str, base_url: str):
- self.name = name
- self.base_url = base_url
-
- @abstractmethod
- async def list_releases(self, *args: Any, **kwargs: Any) -> list[Release]:
- raise NotImplementedError
-
- @abstractmethod
- async def get_release_by_tag_name(self, *args: Any, **kwargs: Any) -> Release:
- raise NotImplementedError
-
- @abstractmethod
- async def get_latest_release(self, *args: Any, **kwargs: Any) -> Release:
- raise NotImplementedError
-
- @abstractmethod
- async def get_latest_pre_release(self, *args: Any, **kwargs: Any) -> Release:
- raise NotImplementedError
-
- @abstractmethod
- async def get_contributors(self, *args: Any, **kwargs: Any) -> list[Contributor]:
- raise NotImplementedError
-
- @abstractmethod
- async def get_patches(self, *args: Any, **kwargs: Any) -> list[dict]:
- raise NotImplementedError
-
- @abstractmethod
- async def get_team_members(self, *args: Any, **kwargs: Any) -> list[Contributor]:
- raise NotImplementedError
-
-
-class Repository:
- """A repository that communicates with a specific backend.
-
- Attributes:
- backend (Backend): The backend instance used to communicate with the repository.
- """
-
- def __init__(self, backend: Backend):
- self.backend = backend
-
-
-class AppInfoProvider(Protocol):
- """Interface for a generic app info provider.
-
- Attributes:
- name (str): Name of the app info provider.
- base_url (str): Base URL of the app info provider.
-
- Methods:
- get_app_info: Retrieve information about an app.
- """
-
- name: str
- base_url: str
-
- def __init__(self, name: str, base_url: str):
- self.name = name
- self.base_url = base_url
-
- @abstractmethod
- async def get_app_info(self, *args: Any, **kwargs: Any) -> AppInfo:
- raise NotImplementedError
diff --git a/api/backends/entities.py b/api/backends/entities.py
deleted file mode 100644
index 1cb022f6..00000000
--- a/api/backends/entities.py
+++ /dev/null
@@ -1,173 +0,0 @@
-from typing import Optional
-from dataclasses import dataclass
-
-
-@dataclass
-class Metadata(dict):
- """
- Represents the metadata of a release.
-
- Attributes:
- - tag_name (str): The name of the release tag.
- - name (str): The name of the release.
- - body (str): The body of the release.
- - draft (bool): Whether the release is a draft.
- - prerelease (bool): Whether the release is a prerelease.
- - created_at (str): The creation date of the release.
- - published_at (str): The publication date of the release.
- """
-
- def __init__(
- self,
- tag_name: str,
- name: str,
- draft: bool,
- prerelease: bool,
- created_at: str,
- published_at: str,
- body: str,
- repository: Optional[str] = None,
- ):
- dict.__init__(
- self,
- tag_name=tag_name,
- name=name,
- draft=draft,
- prerelease=prerelease,
- created_at=created_at,
- published_at=published_at,
- body=body,
- repository=repository,
- )
-
-
-@dataclass
-class Asset(dict):
- """
- Represents an asset in a release.
-
- Attributes:
- - name (str): The name of the asset.
- - content_type (str): The MIME type of the asset content.
- - download_count (int): The number of times the asset has been downloaded.
- - download_url (str): The URL to download the asset.
- """
-
- def __init__(
- self,
- name: str,
- content_type: str,
- download_count: int,
- browser_download_url: str,
- ):
- dict.__init__(
- self,
- name=name,
- content_type=content_type,
- download_count=download_count,
- browser_download_url=browser_download_url,
- )
-
-
-@dataclass
-class Release(dict):
- """
- Represents a release.
-
- Attributes:
- - metadata (Metadata): The metadata of the release.
- - assets (list[Asset]): The assets of the release.
- """
-
- def __init__(self, metadata: Metadata, assets: list[Asset]):
- dict.__init__(self, metadata=metadata, assets=assets)
-
-
-@dataclass
-class Contributor(dict):
- """
- Represents a contributor to a repository.
-
- Attributes:
- - login (str): The GitHub username of the contributor.
- - avatar_url (str): The URL to the contributor's avatar image.
- - html_url (str): The URL to the contributor's GitHub profile.
- - contributions (Optional[int]): The number of contributions the contributor has made to the repository.
- """
-
- def __init__(
- self,
- login: str,
- avatar_url: str,
- html_url: str,
- contributions: Optional[int] = None,
- bio: Optional[str] = None,
- keys: Optional[str] = None,
- ):
- match contributions, bio, keys:
- case None, None, None:
- dict.__init__(
- self,
- login=login,
- avatar_url=avatar_url,
- html_url=html_url,
- bio=bio,
- keys=keys,
- )
- case int(_), None, None:
- dict.__init__(
- self,
- login=login,
- avatar_url=avatar_url,
- html_url=html_url,
- contributions=contributions,
- )
- case None, str(_), None:
- dict.__init__(
- self,
- login=login,
- avatar_url=avatar_url,
- html_url=html_url,
- bio=bio,
- )
- case int(_), str(_), str(_):
- dict.__init__(
- self,
- login=login,
- avatar_url=avatar_url,
- html_url=html_url,
- contributions=contributions,
- bio=bio,
- keys=keys,
- )
- case None, str(_), str(_):
- dict.__init__(
- self,
- login=login,
- avatar_url=avatar_url,
- html_url=html_url,
- bio=bio,
- keys=keys,
- )
- case _:
- raise ValueError("Invalid arguments")
-
-
-@dataclass
-class AppInfo(dict):
- """
- Represents the information of an app.
-
- Attributes:
- - name (str): The name of the app.
- - category (str): The app category.
- - logo (str): The base64 enconded app logo.
- """
-
- def __init__(self, name: str, category: str, logo: str):
- dict.__init__(
- self,
- name=name,
- category=category,
- logo=logo,
- )
diff --git a/api/backends/github.py b/api/backends/github.py
deleted file mode 100644
index f4b07505..00000000
--- a/api/backends/github.py
+++ /dev/null
@@ -1,445 +0,0 @@
-import asyncio
-import os
-from operator import eq
-from typing import Any, Optional
-
-import ujson
-from aiohttp import ClientResponse
-from sanic import SanicException
-from cytoolz import filter, map, partial, curry, pipe
-from cytoolz.dicttoolz import get_in, keyfilter
-from cytoolz.itertoolz import mapcat, pluck
-
-from api.backends.backend import Backend, Repository
-from api.backends.entities import *
-from api.backends.entities import Contributor
-from api.utils.http_utils import http_get
-
-repo_name: str = "github"
-base_url: str = "https://api.github.com"
-
-
-class GithubRepository(Repository):
- """
- A repository class that represents a GitHub repository.
-
- Args:
- owner (str): The username of the owner of the GitHub repository.
- name (str): The name of the GitHub repository.
- """
-
- def __init__(self, owner: str, name: str):
- """
- Initializes a new instance of the GithubRepository class.
-
- Args:
- owner (str): The username of the owner of the GitHub repository.
- name (str): The name of the GitHub repository.
- """
- super().__init__(Github())
- self.owner = owner
- self.name = name
-
-
-class Github(Backend):
- """
- A backend class that interacts with the GitHub API.
-
- Attributes:
- name (str): The name of the GitHub backend.
- base_url (str): The base URL of the GitHub API.
- token (str): The GitHub access token used for authentication.
- headers (dict[str, str]): The HTTP headers to be sent with each request to the GitHub API.
- """
-
- def __init__(self):
- """
- Initializes a new instance of the GitHub class.
- """
- super().__init__(repo_name, base_url)
- self.token: Optional[str] = os.getenv("GITHUB_TOKEN")
- self.headers: dict[str, str] = {
- "Authorization": f"Bearer {self.token}",
- "Accept": "application/vnd.github+json",
- "X-GitHub-Api-Version": "2022-11-28",
- }
- self.repositories_rest_endpoint: str = f"{base_url}/repos"
-
- @staticmethod
- async def __assemble_release(release: dict) -> Release:
- async def __assemble_asset(asset: dict) -> Asset:
- asset_data: dict = keyfilter(
- lambda key: key
- in {"name", "content_type", "download_count", "browser_download_url"},
- asset,
- )
- return Asset(**asset_data)
-
- filter_metadata = keyfilter(
- lambda key: key
- in {
- "tag_name",
- "name",
- "draft",
- "prerelease",
- "created_at",
- "published_at",
- "body",
- },
- release,
- )
- metadata = Metadata(**filter_metadata)
- assets = await asyncio.gather(*map(__assemble_asset, release["assets"]))
- return Release(metadata=metadata, assets=assets)
-
- @staticmethod
- async def __assemble_contributor(
- contributor: dict, team_view: bool = False
- ) -> Contributor:
- match team_view:
- case True:
- keys = {"login", "avatar_url", "html_url", "bio"}
- case _:
- keys = {"login", "avatar_url", "html_url", "contributions"}
-
- filter_contributor = keyfilter(
- lambda key: key in keys,
- contributor,
- )
-
- if team_view:
- filter_contributor[
- "keys"
- ] = f"{base_url.replace('api.', '')}/{filter_contributor['login']}.gpg"
-
- return Contributor(**filter_contributor)
-
- @staticmethod
- async def __validate_request(_response: ClientResponse) -> None:
- if _response.status != 200:
- raise SanicException(
- context=await _response.json(loads=ujson.loads),
- status_code=_response.status,
- )
-
- async def list_releases(
- self, repository: GithubRepository, per_page: int = 30, page: int = 1
- ) -> list[Release]:
- """
- Returns a list of Release objects for a given GitHub repository.
-
- Args:
- repository (GithubRepository): The GitHub repository for which to retrieve the releases.
- per_page (int): The number of releases to return per page.
- page (int): The page number of the releases to return.
-
- Returns:
- list[Release]: A list of Release objects.
- """
- list_releases_endpoint: str = f"{self.repositories_rest_endpoint}/{repository.owner}/{repository.name}/releases?per_page={per_page}&page={page}"
- response: ClientResponse = await http_get(
- headers=self.headers, url=list_releases_endpoint
- )
- await self.__validate_request(response)
- releases: list[Release] = await asyncio.gather(
- *map(
- lambda release: self.__assemble_release(release),
- await response.json(loads=ujson.loads),
- )
- )
- return releases
-
- async def get_release_by_tag_name(
- self, repository: GithubRepository, tag_name: str
- ) -> Release:
- """
- Retrieves a specific release for a given GitHub repository by its tag name.
-
- Args:
- repository (GithubRepository): The GitHub repository for which to retrieve the release.
- tag_name (str): The tag name of the release to retrieve.
-
- Returns:
- Release: The Release object representing the retrieved release.
- """
- release_by_tag_endpoint: str = f"{self.repositories_rest_endpoint}/{repository.owner}/{repository.name}/releases/tags/{tag_name}"
- response: ClientResponse = await http_get(
- headers=self.headers, url=release_by_tag_endpoint
- )
- await self.__validate_request(response)
- return await self.__assemble_release(await response.json(loads=ujson.loads))
-
- async def get_latest_release(
- self,
- repository: GithubRepository,
- ) -> Release:
- """Get the latest release for a given repository.
-
- Args:
- repository (GithubRepository): The GitHub repository for which to retrieve the release.
-
- Returns:
- Release: The latest release for the given repository.
- """
- latest_release_endpoint: str = f"{self.repositories_rest_endpoint}/{repository.owner}/{repository.name}/releases/latest"
- response: ClientResponse = await http_get(
- headers=self.headers, url=latest_release_endpoint
- )
- await self.__validate_request(response)
- return await self.__assemble_release(await response.json(loads=ujson.loads))
-
- async def get_latest_pre_release(
- self,
- repository: GithubRepository,
- ) -> Release:
- """Get the latest pre-release for a given repository.
-
- Args:
- repository (GithubRepository): The GitHub repository for which to retrieve the release.
-
- Returns:
- Release: The latest pre-release for the given repository.
- """
- list_releases_endpoint: str = f"{self.repositories_rest_endpoint}/{repository.owner}/{repository.name}/releases?per_page=10&page=1"
- response: ClientResponse = await http_get(
- headers=self.headers, url=list_releases_endpoint
- )
- await self.__validate_request(response)
- latest_pre_release = next(
- filter(
- lambda release: release["prerelease"],
- await response.json(loads=ujson.loads),
- )
- )
- return await self.__assemble_release(latest_pre_release)
-
- async def get_contributors(self, repository: GithubRepository) -> list[Contributor]:
- """Get a list of contributors for a given repository.
-
- Args:
- repository (GithubRepository): The repository for which to retrieve contributors.
-
- Returns:
- list[Contributor]: A list of contributors for the given repository.
- """
-
- contributors_endpoint: str = f"{self.repositories_rest_endpoint}/{repository.owner}/{repository.name}/contributors"
- response: ClientResponse = await http_get(
- headers=self.headers, url=contributors_endpoint
- )
- await self.__validate_request(response)
- contributors: list[Contributor] = await asyncio.gather(
- *map(self.__assemble_contributor, await response.json(loads=ujson.loads))
- )
-
- return contributors
-
- async def get_patches(
- self, repository: GithubRepository, tag_name: str = "latest", dev: bool = False
- ) -> list[dict]:
- """Get a dictionary of patch URLs for a given repository.
-
- Args:
- repository (GithubRepository): The repository for which to retrieve patches.
- tag_name (str): The name of the release tag.
- dev (bool): If we should get the latest pre-release instead.
-
- Returns:
- list[dict]: A JSON object containing the patches.
- """
-
- async def __fetch_download_url(_release: Release) -> str:
- asset = get_in(["assets"], _release)
- patch_asset = next(
- filter(lambda x: eq(get_in(["name"], x), "patches.json"), asset), None
- )
- return get_in(["browser_download_url"], patch_asset)
-
- match tag_name:
- case "latest":
- match dev:
- case True:
- release = await self.get_latest_pre_release(repository)
- case _:
- release = await self.get_latest_release(repository)
- case _:
- release = await self.get_release_by_tag_name(
- repository=repository, tag_name=tag_name
- )
-
- response: ClientResponse = await http_get(
- headers=self.headers,
- url=await __fetch_download_url(_release=release),
- )
- await self.__validate_request(response)
- return ujson.loads(await response.read())
-
- async def get_team_members(self, repository: GithubRepository) -> list[Contributor]:
- """Get the list of team members from the owner organization of a given repository.
-
- Args:
- repository (GithubRepository): The repository for which to retrieve team members in the owner organization.
-
- Returns:
- list[Contributor]: A list of members in the owner organization.
- """
- team_members_endpoint: str = f"{self.base_url}/orgs/{repository.owner}/members"
- user_info_endpoint: str = f"{self.base_url}/users/"
- response: ClientResponse = await http_get(
- headers=self.headers, url=team_members_endpoint
- )
- await self.__validate_request(response)
- logins: list[str] = list(pluck("login", await response.json()))
- _http_get = partial(http_get, headers=self.headers)
- user_data_response: list[dict] = await asyncio.gather(
- *map(
- lambda login: _http_get(url=f"{user_info_endpoint}{login}"),
- logins,
- )
- )
- user_data = await asyncio.gather(
- *map(
- lambda _response: _response.json(loads=ujson.loads),
- user_data_response,
- )
- )
- team_members: list[Contributor] = await asyncio.gather(
- *map(
- lambda member: self.__assemble_contributor(member, team_view=True),
- list(user_data),
- )
- )
-
- return team_members
-
- async def compat_get_tools(
- self, repositories: list[GithubRepository], dev: bool
- ) -> list:
- """Get the latest releases for a set of repositories (v1 compat).
-
- Args:
- repositories (set[GithubRepository]): The repositories for which to retrieve releases.
- dev: If we should get the latest pre-release instead.
-
- Returns:
- list[dict[str, str]]: A JSON object containing the releases.
- """
-
- def transform(data: dict, repository: GithubRepository):
- """Transforms a dictionary from the input list into a list of dictionaries with the desired structure.
-
- Args:
- data(dict): A dictionary from the input list.
- repository(GithubRepository): The repository for which to retrieve releases.
-
- Returns:
- _[list]: A list of dictionaries with the desired structure.
- """
-
- def process_asset(asset: dict) -> dict:
- """Transforms an asset dictionary into a new dictionary with the desired structure.
-
- Args:
- asset(dict): An asset dictionary.
-
- Returns:
- _[dict]: A new dictionary with the desired structure.
- """
- return {
- "repository": f"{repository.owner}/{repository.name}",
- "version": data["metadata"]["tag_name"],
- "timestamp": data["metadata"]["published_at"],
- "name": asset["name"],
- "browser_download_url": asset["browser_download_url"],
- "content_type": asset["content_type"],
- }
-
- return map(process_asset, data["assets"])
-
- results = await asyncio.gather(
- *map(
- lambda release: self.get_latest_release(release),
- repositories,
- )
- )
-
- return list(mapcat(lambda pair: transform(*pair), zip(results, repositories)))
-
- async def compat_get_contributors(
- self, repositories: list[GithubRepository]
- ) -> list:
- """Get the contributors for a set of repositories (v1 compat).
-
- Args:
- repositories (set[GithubRepository]): The repositories for which to retrieve contributors.
-
- Returns:
- list[dict[str, str]]: A JSON object containing the contributors.
- """
-
- def transform(data: dict, repository: GithubRepository) -> dict[str, Any]:
- """Transforms a dictionary from the input list into a list of dictionaries with the desired structure.
-
- Args:
- data(dict): A dictionary from the input list.
- repository(GithubRepository): The repository for which to retrieve contributors.
-
- Returns:
- _[list]: A list of dictionaries with the desired structure.
- """
- return {
- "name": f"{repository.owner}/{repository.name}",
- "contributors": data,
- }
-
- results = await asyncio.gather(
- *map(
- lambda repository: self.get_contributors(repository),
- repositories,
- )
- )
-
- return list(map(lambda pair: transform(*pair), zip(results, repositories)))
-
- async def generate_custom_sources(
- self, repositories: list[GithubRepository], dev: bool
- ) -> dict[str, dict[str, str]]:
- """Generate a custom sources dictionary for a set of repositories.
-
- Args:
- repositories (list[GithubRepository]): The repositories for which to generate the sources.
- dev (bool): If we should get the latest pre-release instead.
-
- Returns:
- dict[str, dict[str, str]]: A dictionary containing the custom sources.
- """
-
- # Helper functions
- filter_by_name = curry(lambda name, item: name in item["name"])
- filter_patches_jar = curry(
- lambda item: "patches" in item["name"] and item["name"].endswith(".jar")
- )
- get_fields = curry(
- lambda fields, item: {field: item[field] for field in fields}
- )
- rename_key = curry(
- lambda old, new, d: {new if k == old else k: v for k, v in d.items()}
- )
-
- sources = await self.compat_get_tools(repositories, dev)
-
- patches = pipe(
- sources,
- lambda items: next(filter(filter_patches_jar, items), None),
- get_fields(["version", "browser_download_url"]),
- rename_key("browser_download_url", "url"),
- )
-
- integrations = pipe(
- sources,
- lambda items: next(filter(filter_by_name("integrations"), items), None),
- get_fields(["version", "browser_download_url"]),
- rename_key("browser_download_url", "url"),
- )
-
- return {"patches": patches, "integrations": integrations}
diff --git a/api/compat.py b/api/compat.py
deleted file mode 100644
index 993e02af..00000000
--- a/api/compat.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""
-This module provides endpoints for compatibility with the old API.
-
-Routes:
- - GET //releases: Retrieve a list of releases for a GitHub repository.
- - GET //releases/latest: Retrieve the latest release for a GitHub repository.
- - GET //releases/tag/: Retrieve a specific release for a GitHub repository by its tag name.
- - GET //contributors: Retrieve a list of contributors for a GitHub repository.
- - GET /patches/: Retrieve a list of patches for a given release tag.
-
-"""
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.backends.github import Github, GithubRepository
-from api.models.github import *
-from api.models.compat import ToolsResponseModel, ContributorsResponseModel
-from config import compat_repositories, owner
-
-compat: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-github_backend: Github = Github()
-
-
-@compat.get("/tools")
-@openapi.definition(
- summary="Get patching tools' latest version.", response=[ToolsResponseModel]
-)
-async def tools(request: Request) -> JSONResponse:
- """
- Retrieve a list of releases for a GitHub repository.
-
- **Args:**
- - repo (str): The name of the GitHub repository to retrieve releases for.
-
- **Query Parameters:**
- - per_page (int): The number of releases to retrieve per page.
- - page (int): The page number of the releases to retrieve.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of releases.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the releases.
- """
-
- data: dict[str, list] = {
- "tools": await github_backend.compat_get_tools(
- repositories=[
- GithubRepository(owner=owner, name=repo)
- for repo in compat_repositories
- if repo
- not in ["revanced-api", "revanced-releases-api", "revanced-website"]
- ],
- dev=True if request.args.get("dev") else False,
- )
- }
-
- return json(data, status=200)
-
-
-@compat.get("/contributors")
-@openapi.definition(
- summary="Get organization-wise contributors.", response=[ContributorsResponseModel]
-)
-async def contributors(request: Request) -> JSONResponse:
- """
- Retrieve a list of releases for a GitHub repository.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of releases.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the releases.
- """
-
- data: dict[str, list] = {
- "repositories": await github_backend.compat_get_contributors(
- repositories=[
- GithubRepository(owner=owner, name=repo) for repo in compat_repositories
- ]
- )
- }
-
- return json(data, status=200)
diff --git a/api/donations.py b/api/donations.py
deleted file mode 100644
index 25ae875f..00000000
--- a/api/donations.py
+++ /dev/null
@@ -1,38 +0,0 @@
-"""
-This module provides a blueprint for the donations endpoint.
-
-Routes:
- - GET /donations: Get ReVanced donation links and wallets.
-"""
-
-import os
-
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.models.donations import DonationsResponseModel
-from config import wallets, links
-
-donations: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@donations.get("/donations")
-@openapi.definition(
- summary="Get ReVanced donation links and wallets",
- response=[DonationsResponseModel],
-)
-async def root(request: Request) -> JSONResponse:
- """
- Returns a JSONResponse with a dictionary containing ReVanced donation links and wallets.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse instance containing a dictionary with the donation links and wallets.
- """
- data: dict[str, dict] = {
- "donations": {
- "wallets": wallets,
- "links": links,
- }
- }
- return json(data, status=200)
diff --git a/api/github.py b/api/github.py
deleted file mode 100644
index aaf98bc9..00000000
--- a/api/github.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
-This module provides endpoints for interacting with the GitHub API.
-
-Routes:
- - GET //releases: Retrieve a list of releases for a GitHub repository.
- - GET //releases/latest: Retrieve the latest release for a GitHub repository.
- - GET //releases/tag/: Retrieve a specific release for a GitHub repository by its tag name.
- - GET //contributors: Retrieve a list of contributors for a GitHub repository.
- - GET /patches/: Retrieve a list of patches for a given release tag.
-
-"""
-
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.backends.entities import Release, Contributor
-from api.backends.github import Github, GithubRepository
-from api.models.github import *
-from config import owner, default_repository
-
-github: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-github_backend: Github = Github()
-
-
-@github.get("//releases")
-@openapi.definition(
- summary="Get releases for a repository", response=[ReleaseListResponseModel]
-)
-async def list_releases(request: Request, repo: str) -> JSONResponse:
- """
- Retrieve a list of releases for a GitHub repository.
-
- **Args:**
- - repo (str): The name of the GitHub repository to retrieve releases for.
-
- **Query Parameters:**
- - per_page (int): The number of releases to retrieve per page.
- - page (int): The page number of the releases to retrieve.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of releases.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the releases.
- """
-
- per_page = int(request.args.get("per_page")) if request.args.get("per_page") else 30
- page = int(request.args.get("page")) if request.args.get("page") else 1
-
- data: dict[str, list[Release]] = {
- "releases": await github_backend.list_releases(
- repository=GithubRepository(owner=owner, name=repo),
- per_page=per_page,
- page=page,
- )
- }
-
- return json(data, status=200)
-
-
-@github.get("//releases/latest")
-@openapi.definition(
- summary="Get the latest release for a repository",
- response=SingleReleaseResponseModel,
-)
-async def latest_release(request: Request, repo: str) -> JSONResponse:
- """
- Retrieve the latest release for a GitHub repository.
-
- **Args:**
- - repo (str): The name of the GitHub repository to retrieve the release for.
-
- **Query Parameters:**
- - dev (bool): Whether or not to retrieve the latest development release.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the release.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the releases.
- """
-
- data: dict[str, Release]
-
- match request.args.get("dev"):
- case "true":
- data = {
- "release": await github_backend.get_latest_pre_release(
- repository=GithubRepository(owner=owner, name=repo)
- )
- }
- case _:
- data = {
- "release": await github_backend.get_latest_release(
- repository=GithubRepository(owner=owner, name=repo)
- )
- }
-
- return json(data, status=200)
-
-
-@github.get("//releases/tag/")
-@openapi.definition(
- summary="Retrieve a release for a GitHub repository by its tag name.",
- response=SingleReleaseResponseModel,
-)
-async def get_release_by_tag_name(
- request: Request, repo: str, tag: str
-) -> JSONResponse:
- """
- Retrieve a release for a GitHub repository by its tag name.
-
- **Args:**
- - repo (str): The name of the GitHub repository to retrieve the release for.
- - tag (str): The tag for the release to be retrieved.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the release.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the releases.
- """
-
- data: dict[str, Release] = {
- "release": await github_backend.get_release_by_tag_name(
- repository=GithubRepository(owner=owner, name=repo), tag_name=tag
- )
- }
-
- return json(data, status=200)
-
-
-@github.get("//contributors")
-@openapi.definition(
- summary="Retrieve a list of contributors for a repository.",
- response=ContributorsModel,
-)
-async def get_contributors(request: Request, repo: str) -> JSONResponse:
- """
- Retrieve a list of contributors for a repository.
-
- **Args:**
- - repo (str): The name of the GitHub repository to retrieve the contributors for.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of contributors.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the contributors.
- """
-
- data: dict[str, list[Contributor]] = {
- "contributors": await github_backend.get_contributors(
- repository=GithubRepository(owner=owner, name=repo)
- )
- }
-
- return json(data, status=200)
-
-
-@github.get("/patches/")
-@openapi.definition(
- summary="Retrieve a list of patches for a release.", response=PatchesModel
-)
-async def get_patches(request: Request, tag: str) -> JSONResponse:
- """
- Retrieve a list of patches for a release.
-
- **Args:**
- - tag (str): The tag for the patches to be retrieved.
-
- **Query Parameters:**
- - dev (bool): Whether or not to retrieve the latest development release.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of patches.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the patches.
- """
-
- repo: str = "revanced-patches"
-
- dev: bool = bool(request.args.get("dev"))
-
- data: dict[str, list[dict]] = {
- "patches": await github_backend.get_patches(
- repository=GithubRepository(owner=owner, name=repo), tag_name=tag, dev=dev
- )
- }
-
- return json(data, status=200)
-
-
-@github.get("/team/members")
-@openapi.definition(
- summary="Retrieve a list of team members for the Revanced organization.",
- response=TeamMembersModel,
-)
-async def get_team_members(request: Request) -> JSONResponse:
- """
- Retrieve a list of team members for the Revanced organization.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the list of team members.
-
- **Raises:**
- - HTTPException: If there is an error retrieving the team members.
- """
-
- data: dict[str, list[Contributor]] = {
- "members": await github_backend.get_team_members(
- repository=GithubRepository(owner=owner, name=default_repository)
- )
- }
-
- return json(data, status=200)
diff --git a/api/info.py b/api/info.py
deleted file mode 100644
index 60fbeac5..00000000
--- a/api/info.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""
-This module provides a blueprint for the info endpoint.
-
-Routes:
- - GET /info: Get info about the owner of the API.
-"""
-
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.models.info import InfoResponseModel
-from config import default_info
-
-info: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@info.get("/info")
-@openapi.definition(
- summary="Information about the API",
- response=[InfoResponseModel],
-)
-async def root(request: Request) -> JSONResponse:
- """
- Returns a JSONResponse with a dictionary containing info about the owner of the API.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse instance containing a dictionary with the info about the owner of the API.
- """
- data: dict[str, dict] = {"info": default_info}
- return json(data, status=200)
diff --git a/api/login.py b/api/login.py
deleted file mode 100644
index 939960b6..00000000
--- a/api/login.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""
-This module provides a blueprint for the login endpoint.
-
-Routes:
- - POST /login: Login to the API
-"""
-
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-from sanic_beskar.exceptions import AuthenticationError
-
-from api.utils.auth import beskar
-from api.utils.limiter import limiter
-
-login: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@login.post("/login")
-@openapi.definition(
- summary="Login to the API",
-)
-@limiter.limit("3 per hour")
-async def login_user(request: Request) -> JSONResponse:
- """
- Login to the API.
-
- **Args:**
- - username (str): The username of the user to login.
- - password (str): The password of the user to login.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse object containing the access token.
- """
-
- req = request.json
- username = req.get("username", None)
- password = req.get("password", None)
- if not username or not password:
- return json({"error": "Missing username or password"}, status=400)
-
- try:
- user = await beskar.authenticate(username, password)
- except AuthenticationError:
- return json({"error": "Invalid username or password"}, status=403)
-
- if not user:
- return json({"error": "Invalid username or password"}, status=403)
-
- ret = {"access_token": await beskar.encode_token(user)}
- return json(ret, status=200)
diff --git a/api/manager.py b/api/manager.py
deleted file mode 100644
index 87a3e602..00000000
--- a/api/manager.py
+++ /dev/null
@@ -1,61 +0,0 @@
-"""
-This module provides ReVanced Manager specific endpoints.
-
-Routes:
- - GET /manager/bootstrap: Get a list of the main ReVanced tools.
- - GET /manager/sources: Get a list of ReVanced sources.
-"""
-
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.backends.github import GithubRepository, Github
-
-from api.models.manager import BootsrapResponseModel, CustomSourcesResponseModel
-from config import compat_repositories, owner
-
-manager: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-github_backend: Github = Github()
-
-
-@manager.get("/manager/bootstrap")
-@openapi.definition(
- summary="Get a list of the main ReVanced tools",
- response=[BootsrapResponseModel],
-)
-async def bootstrap(request: Request) -> JSONResponse:
- """
- Returns a JSONResponse with a list of the main ReVanced tools.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse instance containing a list with the tool names.
- """
- data: dict[str, dict] = {"tools": compat_repositories}
- return json(data, status=200)
-
-
-@manager.get("/manager/custom-source")
-@openapi.definition(
- summary="Get a list of ReVanced sources",
- response=[CustomSourcesResponseModel],
-)
-async def custom_sources(request: Request) -> JSONResponse:
- """
- Returns a JSONResponse with a list of the main ReVanced sources.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse instance containing a list with the source names.
- """
- data = await github_backend.generate_custom_sources(
- repositories=[
- GithubRepository(owner=owner, name=repo)
- for repo in compat_repositories
- if "patches" in repo or "integrations" in repo
- ],
- dev=True if request.args.get("dev") else False,
- )
-
- return json(data, status=200)
diff --git a/api/models/__init__.py b/api/models/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/api/models/announcements.py b/api/models/announcements.py
deleted file mode 100644
index 86047219..00000000
--- a/api/models/announcements.py
+++ /dev/null
@@ -1,37 +0,0 @@
-from data.models import AnnouncementDbModel
-
-
-class ContentFields(dict):
- message: str | None
- attachment_urls: list[str] | None
-
-
-class AnnouncementResponseModel(dict):
- id: int
- author: str | None
- title: str
- content: ContentFields | None
- channel: str
- created_at: str
- level: int | None
-
- @staticmethod
- def to_response(announcement: AnnouncementDbModel):
- response = AnnouncementResponseModel(
- id=announcement.id,
- author=announcement.author,
- title=announcement.title,
- content=ContentFields(
- message=announcement.message,
- attachment_urls=[
- attachment.attachment_url for attachment in announcement.attachments
- ],
- )
- if announcement.message or announcement.attachments
- else None,
- channel=announcement.channel,
- created_at=str(announcement.created_at),
- level=announcement.level,
- )
-
- return response
diff --git a/api/models/compat.py b/api/models/compat.py
deleted file mode 100644
index b1876136..00000000
--- a/api/models/compat.py
+++ /dev/null
@@ -1,49 +0,0 @@
-from pydantic import BaseModel
-from api.models.github import ContributorsFields
-
-
-class ToolsResponseFields(BaseModel):
- """Implements the fields for the /tools endpoint.
-
- Args:
- BaseModel (pydantic.BaseModel): BaseModel from pydantic
- """
-
- repository: str
- version: str
- timestamp: str
- name: str
- size: str | None = None
- browser_download_url: str
- content_type: str
-
-
-class ToolsResponseModel(BaseModel):
- """Implements the JSON response model for the /tools endpoint.
-
- Args:
- BaseModel (pydantic.BaseModel): BaseModel from pydantic
- """
-
- tools: list[ToolsResponseFields]
-
-
-class ContributorsResponseFields(BaseModel):
- """Implements the fields for the /contributors endpoint.
-
- Args:
- BaseModel (pydantic.BaseModel): BaseModel from pydantic
- """
-
- name: str
- contributors: list[ContributorsFields]
-
-
-class ContributorsResponseModel(BaseModel):
- """Implements the JSON response model for the /contributors endpoint.
-
- Args:
- BaseModel (pydantic.BaseModel): BaseModel from pydantic
- """
-
- repositories: list[ContributorsResponseFields]
diff --git a/api/models/donations.py b/api/models/donations.py
deleted file mode 100644
index 12ad18ba..00000000
--- a/api/models/donations.py
+++ /dev/null
@@ -1,39 +0,0 @@
-from pydantic import BaseModel
-
-
-class WalletFields(BaseModel):
- """
- Implements the fields for a crypto wallet.
- """
-
- network: str
- currency_code: str
- address: str
- preferred: bool
-
-
-class LinkFields(BaseModel):
- """
- Implements the fields for a donation link.
- """
-
- name: str
- url: str
- preferred: bool
-
-
-class DonationFields(BaseModel):
- """
- A Pydantic BaseModel that represents all the donation links and wallets.
- """
-
- wallets: list[WalletFields]
- links: list[LinkFields]
-
-
-class DonationsResponseModel(BaseModel):
- """
- A Pydantic BaseModel that represents a dictionary of donation links.
- """
-
- donations: DonationFields
diff --git a/api/models/github.py b/api/models/github.py
deleted file mode 100644
index e2f246af..00000000
--- a/api/models/github.py
+++ /dev/null
@@ -1,129 +0,0 @@
-from typing import Any, Optional
-from pydantic import BaseModel
-
-
-class MetadataFields(BaseModel):
- """
- Metadata fields for a GitHub release.
- """
-
- tag_name: str
- name: str
- draft: bool
- prerelease: bool
- created_at: str
- published_at: str
- body: str
-
-
-class AssetFields(BaseModel):
- """
- Asset fields for a GitHub release.
- """
-
- name: str
- content_type: str
- download_count: int
- browser_download_url: str
-
-
-class ReleaseResponseModel(BaseModel):
- """
- Response model for a GitHub release.
- """
-
- metadata: MetadataFields
- assets: list[AssetFields]
-
-
-class SingleReleaseResponseModel(BaseModel):
- """
- Response model for a GitHub release.
- """
-
- release: ReleaseResponseModel
-
-
-class ReleaseListResponseModel(BaseModel):
- """
- Response model for a list of GitHub releases.
- """
-
- releases: list[ReleaseResponseModel]
-
-
-class CompatiblePackagesResponseFields(BaseModel):
- """
- Implements the fields for compatible packages in the PatchesResponseFields class.
- """
-
- name: str
- versions: list[str] | None
-
-
-class PatchesOptionsResponseFields(BaseModel):
- key: str
- title: str
- description: str
- required: bool
- choices: list[Any] | None
-
-
-class PatchesResponseFields(BaseModel):
- """
- Implements the fields for the /patches endpoint.
- """
-
- name: str
- description: str
- version: str
- excluded: bool
- dependencies: list[str] | None
- options: list[PatchesOptionsResponseFields] | None
- compatiblePackages: list[CompatiblePackagesResponseFields]
-
-
-class PatchesModel(BaseModel):
- """
- Response model for a list of GitHub releases.
- """
-
- patches: list[PatchesResponseFields]
-
-
-class ContributorsFields(BaseModel):
- """
- Implements the fields for a contributor.
- """
-
- login: str
- avatar_url: str
- html_url: str
- contributions: Optional[int]
-
-
-class ContributorsModel(BaseModel):
- """
- Response model for a list of contributors.
- """
-
- contributors: list[ContributorsFields]
-
-
-class TeamMemberFields(BaseModel):
- """
- Implements the fields for a team member.
- """
-
- login: str
- avatar_url: str
- html_url: str
- bio: Optional[str]
-
-
-class TeamMembersModel(BaseModel):
- """
- Responde model for a list of team members.
- """
-
- members: list[TeamMemberFields]
diff --git a/api/models/info.py b/api/models/info.py
deleted file mode 100644
index 06b102c1..00000000
--- a/api/models/info.py
+++ /dev/null
@@ -1,40 +0,0 @@
-from api.models.donations import DonationFields
-from api.models.socials import SocialFields
-from pydantic import BaseModel
-
-
-class ContactFields(BaseModel):
- """
- Implements the fields for the API owner contact info.
- """
-
- email: str
-
-
-class BrandingFields(BaseModel):
- """
- Implements the fields for the API owner branding info.
- """
-
- logo: str
-
-
-class InfoFields(BaseModel):
- """
- Implements the fields for the API owner info.
- """
-
- name: str
- about: str
- branding: BrandingFields
- contact: ContactFields
- socials: list[SocialFields]
- donations: DonationFields
-
-
-class InfoResponseModel(BaseModel):
- """
- A Pydantic BaseModel that represents a dictionary of info.
- """
-
- info: InfoFields
diff --git a/api/models/manager.py b/api/models/manager.py
deleted file mode 100644
index c7e39b3b..00000000
--- a/api/models/manager.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from pydantic import BaseModel
-
-
-class BootsrapResponseModel(BaseModel):
- """
- A Pydantic BaseModel that represents a list of available tools.
- """
-
- tools: list[str]
- """
- A list of available tools.
- """
-
-
-class CustomSourcesFields(BaseModel):
- """
- Implements the fields for a source.
- """
-
- url: str
- preferred: bool
-
-
-class CustomSourcesResponseModel(BaseModel):
- """
- A Pydantic BaseModel that represents a list of available sources.
- """
-
- _: dict[str, CustomSourcesFields]
- """
- A list of available sources.
- """
diff --git a/api/models/socials.py b/api/models/socials.py
deleted file mode 100644
index 45edad01..00000000
--- a/api/models/socials.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from pydantic import BaseModel
-
-
-class SocialFields(BaseModel):
- """
- Implements the fields for a social network link.
- """
-
- name: str
- url: str
- preferred: bool
-
-
-class SocialsResponseModel(BaseModel):
- """
- A Pydantic BaseModel that represents a dictionary of social links.
- """
-
- socials: list[SocialFields]
- """
- A dictionary where the keys are the names of the social networks, and
- the values are the links to the profiles or pages.
- """
diff --git a/api/ping.py b/api/ping.py
deleted file mode 100644
index 09bce092..00000000
--- a/api/ping.py
+++ /dev/null
@@ -1,24 +0,0 @@
-"""
-This module provides endpoints for pinging the API.
-
-Routes:
- - GET /ping: Ping the API.
-"""
-
-import os
-from sanic import Blueprint, HTTPResponse, Request, response
-from sanic_ext import openapi
-
-ping: Blueprint = Blueprint(os.path.basename(__file__).rstrip(".py"))
-
-
-@ping.get("/ping")
-@openapi.summary("Ping the API")
-async def root(request: Request) -> HTTPResponse:
- """
- Endpoint for pinging the API.
-
- **Returns:**
- - Empty response with status code 204.
- """
- return response.empty(status=204)
diff --git a/api/robots.py b/api/robots.py
deleted file mode 100644
index 10460c32..00000000
--- a/api/robots.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import os
-from sanic import Blueprint
-from sanic.response import text
-
-
-robots: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@robots.get("/robots.txt")
-async def robots_txt(request):
- return text("User-agent: *\nDisallow: /", content_type="text/plain")
diff --git a/api/socials.py b/api/socials.py
deleted file mode 100644
index f58dcc66..00000000
--- a/api/socials.py
+++ /dev/null
@@ -1,32 +0,0 @@
-"""
-This module provides a blueprint for the socials endpoint.
-
-Routes:
- - GET /socials: Get ReVanced socials.
-"""
-
-import os
-from sanic import Blueprint, Request
-from sanic.response import JSONResponse, json
-from sanic_ext import openapi
-
-from api.models.socials import SocialsResponseModel
-from config import social_links
-
-socials: Blueprint = Blueprint(os.path.basename(__file__).strip(".py"))
-
-
-@socials.get("/socials")
-@openapi.definition(
- summary="Get ReVanced socials",
- response=[SocialsResponseModel],
-)
-async def root(request: Request) -> JSONResponse:
- """
- Returns a JSONResponse with a dictionary containing ReVanced social links.
-
- **Returns:**
- - JSONResponse: A Sanic JSONResponse instance containing a dictionary with the social links.
- """
- data: dict[str, dict] = {"socials": social_links}
- return json(data, status=200)
diff --git a/api/utils/__init__.py b/api/utils/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/api/utils/auth.py b/api/utils/auth.py
deleted file mode 100644
index f336a0f8..00000000
--- a/api/utils/auth.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import os
-import secrets
-import string
-from data.database import Session
-
-from sanic_beskar import Beskar
-
-from data.models import UserDbModel
-
-beskar = Beskar()
-
-
-def configure_auth(app):
- app.config.SECRET_KEY = os.environ.get("SECRET_KEY").join(
- secrets.choice(string.ascii_letters) for i in range(15)
- )
- app.config["TOKEN_ACCESS_LIFESPAN"] = {"hours": 24}
- app.config["TOKEN_REFRESH_LIFESPAN"] = {"days": 30}
- beskar.init_app(app, UserDbModel)
-
- _init_default_user()
-
-
-def _init_default_user():
- username = os.environ.get("USERNAME")
- password = os.environ.get("PASSWORD")
-
- if not username or not password:
- raise Exception("Missing USERNAME or PASSWORD environment variables")
-
- session = Session()
-
- existing_user = session.query(UserDbModel).filter_by(username=username).first()
- if not existing_user:
- session.add(
- UserDbModel(username=username, password=beskar.hash_password(password))
- )
- session.commit()
-
- session.close()
diff --git a/api/utils/http_utils.py b/api/utils/http_utils.py
deleted file mode 100644
index 98c9e30a..00000000
--- a/api/utils/http_utils.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Optional
-
-import ujson
-from aiohttp import ClientSession
-
-_client: Optional[ClientSession] = None
-
-
-async def http_get(headers, url):
- """
- Performs a GET HTTP request to a given URL with the provided headers.
-
- Args:
- headers (dict): A dictionary containing headers to be included in the HTTP request.
- url (str): The URL to which the HTTP request will be made.
-
- Returns:
- The HTTP response returned by the server.
- """
- global _client
- if _client is None:
- _client = ClientSession(json_serialize=ujson.dumps)
- return await _client.get(url, headers=headers)
- else:
- assert isinstance(_client, ClientSession)
- return await _client.get(url, headers=headers)
diff --git a/api/utils/limiter.py b/api/utils/limiter.py
deleted file mode 100644
index 5198ca27..00000000
--- a/api/utils/limiter.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from sanic_limiter import Limiter, get_remote_address
-
-limiter = Limiter(key_func=get_remote_address)
-
-
-def configure_limiter(app):
- limiter.init_app(app)
diff --git a/api/utils/versioning.py b/api/utils/versioning.py
deleted file mode 100644
index ad69dd4b..00000000
--- a/api/utils/versioning.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from cytoolz import keyfilter
-from config import api_versions
-
-
-def get_version(value: str) -> str:
- result = keyfilter(lambda key: value in api_versions[key], api_versions)
-
- return list(result.keys())[0] if result else "v0"
diff --git a/app.py b/app.py
deleted file mode 100644
index af8a7a7c..00000000
--- a/app.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# app.py
-
-import os
-from typing import Any
-
-from sanic import HTTPResponse, Sanic
-import sanic.response
-from sanic_ext import Config
-
-from api import api
-from config import openapi_title, openapi_version, openapi_description, hostnames
-
-from api.utils.limiter import configure_limiter
-from api.utils.auth import configure_auth
-
-import sentry_sdk
-
-if os.environ.get("SENTRY_DSN"):
- sentry_sdk.init(
- dsn=os.environ["SENTRY_DSN"],
- enable_tracing=True,
- traces_sample_rate=1.0,
- )
-else:
- print("WARNING: Sentry DSN not set, not enabling Sentry")
-
-REDIRECTS = {
- "/": "/docs/swagger",
-}
-
-app = Sanic("revanced-api")
-app.extend(config=Config(oas_ignore_head=False))
-app.ext.openapi.describe(
- title=openapi_title,
- version=openapi_version,
- description=openapi_description,
-)
-app.config.CORS_ALWAYS_SEND = True
-app.config.CORS_AUTOMATIC_OPTIONS = True
-app.config.CORS_VARY_HEADER = True
-app.config.CORS_METHODS = ["GET", "HEAD", "OPTIONS"]
-app.config.CORS_SUPPORTS_CREDENTIALS = True
-app.config.CORS_SEND_WILDCARD = True
-app.config.CORS_ORIGINS = "*"
-
-# sanic-beskar
-configure_auth(app)
-
-# sanic-limiter
-configure_limiter(app)
-
-app.blueprint(api)
-
-# https://sanic.dev/en/guide/how-to/static-redirects.html
-
-
-def get_static_function(value) -> Any:
- return lambda *_, **__: value
-
-
-for src, dest in REDIRECTS.items():
- app.route(src)(get_static_function(sanic.response.redirect(dest)))
-
-
-@app.on_request
-async def domain_check(request) -> HTTPResponse:
- if request.host not in hostnames:
- return sanic.response.redirect(f"https://api.revanced.app/{request.path}")
-
-
-@app.on_response
-async def add_cache_control(_, response):
- response.headers["Cache-Control"] = "public, max-age=300"
-
-
-@app.on_response
-async def add_csp(_, response):
- response.headers[
- "Content-Security-Policy"
- ] = "default-src * 'unsafe-inline' 'unsafe-eval' data: blob:;"
-
-
-app.static(
- "/favicon.ico",
- "static/img/favicon.ico",
- name="favicon",
-)
diff --git a/assets/revanced-headline/revanced-headline-vertical-dark.svg b/assets/revanced-headline/revanced-headline-vertical-dark.svg
new file mode 100644
index 00000000..a59bfb50
--- /dev/null
+++ b/assets/revanced-headline/revanced-headline-vertical-dark.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/revanced-headline/revanced-headline-vertical-light.svg b/assets/revanced-headline/revanced-headline-vertical-light.svg
new file mode 100644
index 00000000..3c5eeccc
--- /dev/null
+++ b/assets/revanced-headline/revanced-headline-vertical-light.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/revanced-logo/revanced-logo.svg b/assets/revanced-logo/revanced-logo.svg
new file mode 100644
index 00000000..901e1914
--- /dev/null
+++ b/assets/revanced-logo/revanced-logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/build.gradle.kts b/build.gradle.kts
new file mode 100644
index 00000000..0ee566e0
--- /dev/null
+++ b/build.gradle.kts
@@ -0,0 +1,120 @@
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget
+
+plugins {
+ alias(libs.plugins.kotlin)
+ alias(libs.plugins.ktor)
+ alias(libs.plugins.serilization)
+ `maven-publish`
+ signing
+}
+
+group = "app.revanced"
+
+tasks {
+ processResources {
+ expand("projectVersion" to project.version)
+ }
+
+ // Used by gradle-semantic-release-plugin.
+ // Tracking: https://github.com/KengoTODA/gradle-semantic-release-plugin/issues/435.
+ publish {
+ dependsOn(shadowJar)
+ }
+
+ shadowJar {
+ // Needed for Jetty to work.
+ mergeServiceFiles()
+ }
+}
+
+application {
+ mainClass.set("app.revanced.api.command.MainCommandKt")
+}
+
+ktor {
+ fatJar {
+ archiveFileName.set("${project.name}-${project.version}.jar")
+ }
+}
+
+java {
+ sourceCompatibility = JavaVersion.VERSION_21
+ targetCompatibility = JavaVersion.VERSION_21
+}
+
+kotlin {
+ compilerOptions {
+ jvmTarget = JvmTarget.JVM_21
+ }
+}
+
+repositories {
+ mavenCentral()
+ google()
+ mavenLocal()
+ maven {
+ // A repository must be specified for some reason. "registry" is a dummy.
+ url = uri("https://maven.pkg.github.com/revanced/registry")
+ credentials {
+ username = project.findProperty("gpr.user") as String? ?: System.getenv("GITHUB_ACTOR")
+ password = project.findProperty("gpr.key") as String? ?: System.getenv("GITHUB_TOKEN")
+ }
+ }
+}
+
+dependencies {
+ implementation(libs.ktor.client.core)
+ implementation(libs.ktor.client.cio)
+ implementation(libs.ktor.client.okhttp)
+ implementation(libs.ktor.client.auth)
+ implementation(libs.ktor.client.resources)
+ implementation(libs.ktor.client.content.negotiation)
+ implementation(libs.ktor.server.core)
+ implementation(libs.ktor.server.content.negotiation)
+ implementation(libs.ktor.server.auth)
+ implementation(libs.ktor.server.auth.jwt)
+ implementation(libs.ktor.server.cors)
+ implementation(libs.ktor.server.caching.headers)
+ implementation(libs.ktor.server.rate.limit)
+ implementation(libs.ktor.server.host.common)
+ implementation(libs.ktor.server.jetty)
+ implementation(libs.ktor.server.call.logging)
+ implementation(libs.ktor.serialization.kotlinx.json)
+ implementation(libs.koin.ktor)
+ implementation(libs.kompendium.core)
+ implementation(libs.h2)
+ implementation(libs.logback.classic)
+ implementation(libs.exposed.core)
+ implementation(libs.exposed.jdbc)
+ implementation(libs.exposed.dao)
+ implementation(libs.exposed.kotlin.datetime)
+ implementation(libs.dotenv.kotlin)
+ implementation(libs.ktoml.core)
+ implementation(libs.ktoml.file)
+ implementation(libs.picocli)
+ implementation(libs.kotlinx.datetime)
+ implementation(libs.revanced.patcher)
+ implementation(libs.revanced.library)
+ implementation(libs.caffeine)
+ implementation(libs.bouncy.castle.provider)
+ implementation(libs.bouncy.castle.pgp)
+}
+
+// The maven-publish plugin is necessary to make signing work.
+publishing {
+ repositories {
+ mavenLocal()
+ }
+
+ publications {
+ create("revanced-api-publication") {
+ from(components["java"])
+ }
+ }
+}
+
+signing {
+ useGpgCmd()
+
+ sign(publishing.publications["revanced-api-publication"])
+}
diff --git a/config.py b/config.py
deleted file mode 100644
index aee86103..00000000
--- a/config.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# API Configuration
-
-from typing import Any
-
-
-backend: str = "github"
-redis: dict[str, str | int] = {"host": "localhost", "port": 6379}
-hostnames: list[str] = [
- "api.revanced.app",
- "deimos.revanced.app",
- "localhost:8000",
- "127.0.0.1:8000",
-]
-
-# GitHub Backend Configuration
-
-owner: str = "revanced"
-default_repository: str = ".github"
-
-# API Versioning
-
-api_versions: dict[str, list[str]] = {
- "old": ["compat"],
- "v2": [
- "announcements",
- "donations",
- "github",
- "info",
- "login",
- "ping",
- "socials",
- "manager",
- ],
-}
-
-api_version: str = "v2"
-openapi_version: str = "2.0.0"
-openapi_title: str = "ReVanced API"
-openapi_description: str = """
-## The official JSON API for ReVanced Releases đ
-
-### Links
-
-- [Changelogs](https://github.com/revanced/)
-- [Official links to ReVanced](https://revanced.app)
-
-### Important Information
-
-* Rate Limiting - 60 requests per minute
-* Cache - 5 minutes
-
-### Additional Notes
-
-1. Breaking changes are to be expected
-2. Client side caching is advised to avoid unnecessary requests
-3. Abuse of the API will result in IP blocks
-"""
-
-# Testing Configuration
-
-github_testing_repository: str = "revanced-patches"
-github_testing_tag: str = "v2.173.0"
-apkdl_testing_package: str = "com.google.android.youtube"
-
-# Old API Configuration
-
-compat_api_version: str = "v1"
-compat_repositories: list = [
- "revanced-patcher",
- "revanced-patches",
- "revanced-integrations",
- "revanced-manager",
- "revanced-cli",
- "revanced-website",
- "revanced-api",
- "revanced-releases-api",
-]
-
-# Social Links
-
-social_links: list[dict[str, str | bool]] = [
- {"name": "Website", "url": "https://revanced.app", "preferred": True},
- {"name": "GitHub", "url": "https://github.com/revanced", "preferred": False},
- {"name": "Twitter", "url": "https://twitter.com/revancedapp", "preferred": False},
- {"name": "Discord", "url": "https://revanced.app/discord", "preferred": True},
- {
- "name": "Reddit",
- "url": "https://www.reddit.com/r/revancedapp",
- "preferred": False,
- },
- {"name": "Telegram", "url": "https://t.me/app_revanced", "preferred": False},
- {"name": "YouTube", "url": "https://www.youtube.com/@ReVanced", "preferred": False},
-]
-
-# Donation info
-
-wallets: list[dict[str, str | bool]] = [
- {
- "network": "Bitcoin",
- "currency_code": "BTC",
- "address": "bc1q4x8j6mt27y5gv0q625t8wkr87ruy8fprpy4v3f",
- "preferred": False,
- },
- {
- "network": "Dogecoin",
- "currency_code": "DOGE",
- "address": "D8GH73rNjudgi6bS2krrXWEsU9KShedLXp",
- "preferred": True,
- },
- {
- "network": "Ethereum",
- "currency_code": "ETH",
- "address": "0x7ab4091e00363654bf84B34151225742cd92FCE5",
- "preferred": False,
- },
- {
- "network": "Litecoin",
- "currency_code": "LTC",
- "address": "LbJi8EuoDcwaZvykcKmcrM74jpjde23qJ2",
- "preferred": False,
- },
- {
- "network": "Monero",
- "currency_code": "XMR",
- "address": "46YwWDbZD6jVptuk5mLHsuAmh1BnUMSjSNYacozQQEraWSQ93nb2yYVRHoMR6PmFYWEHsLHg9tr1cH5M8Rtn7YaaGQPCjSh",
- "preferred": False,
- },
-]
-
-links: list[dict[str, str | bool]] = [
- {
- "name": "Open Collective",
- "url": "https://opencollective.com/revanced",
- "preferred": True,
- },
- {
- "name": "GitHub Sponsors",
- "url": "https://github.com/sponsors/ReVanced",
- "preferred": False,
- },
-]
-
-default_info: dict[str, Any] = {
- "name": "ReVanced",
- "about": "ReVanced was born out of Vanced's discontinuation and it is our goal to continue the legacy of what Vanced left behind. Thanks to ReVanced Patcher, it's possible to create long-lasting patches for nearly any Android app. ReVanced's patching system is designed to allow patches to work on new versions of the apps automatically with bare minimum maintenance.",
- "branding": {
- "logo": "https://raw.githubusercontent.com/ReVanced/revanced-branding/main/assets/revanced-logo/revanced-logo.svg"
- },
- "contact": {"email": "contact@revanced.app"},
- "socials": social_links,
- "donations": {"wallets": wallets, "links": links},
-}
diff --git a/configuration.example.toml b/configuration.example.toml
new file mode 100644
index 00000000..0ad3059d
--- /dev/null
+++ b/configuration.example.toml
@@ -0,0 +1,19 @@
+organization = "revanced"
+patches = { repository = "revanced-patches", asset-regex = "jar$", signature-asset-regex = "asc$", public-key-file = "patches-public-key.asc" }
+integrations = { repository = "revanced-integrations", asset-regex = "apk$", signature-asset-regex = "asc$", public-key-file = "integrations-public-key.asc" }
+manager = { repository = "revanced-manager", asset-regex = "apk$" }
+contributors-repositories = [
+ "revanced-patcher",
+ "revanced-patches",
+ "revanced-integrations",
+ "revanced-website",
+ "revanced-cli",
+ "revanced-manager",
+]
+api-version = 1
+cors-allowed-hosts = [
+ "revanced.app",
+ "*.revanced.app"
+]
+endpoint = "https://api.revanced.app"
+old-api-endpoint = "https://old-api.revanced.app"
diff --git a/data/database.py b/data/database.py
deleted file mode 100644
index ad93c569..00000000
--- a/data/database.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from sqlalchemy import create_engine
-from sqlalchemy.orm import sessionmaker
-
-engine = create_engine("sqlite:///persistence/database.db", pool_size=20)
-
-Session = sessionmaker(bind=engine)
diff --git a/data/models.py b/data/models.py
deleted file mode 100644
index 36621baa..00000000
--- a/data/models.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from sqlalchemy import Column, Integer, String, DateTime
-from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import relationship
-from sqlalchemy import ForeignKey
-
-from data.database import Session, engine
-
-Base = declarative_base()
-
-
-class AnnouncementDbModel(Base):
- __tablename__ = "announcements"
-
- id = Column(Integer, primary_key=True, autoincrement=True)
- author = Column(String, nullable=True)
- title = Column(String, nullable=False)
- message = Column(String, nullable=True)
- attachments = relationship("AttachmentDbModel", back_populates="announcements")
- channel = Column(String, nullable=True)
- created_at = Column(DateTime, nullable=False)
- level = Column(Integer, nullable=True)
-
-
-class AttachmentDbModel(Base):
- __tablename__ = "attachments"
-
- id = Column(Integer, primary_key=True, autoincrement=True)
- announcement_id = Column(Integer, ForeignKey("announcements.id"))
- attachment_url = Column(String, nullable=False)
-
- announcements = relationship("AnnouncementDbModel", back_populates="attachments")
-
-
-class UserDbModel(Base):
- __tablename__ = "users"
-
- id = Column(Integer, primary_key=True, autoincrement=True)
- username = Column(String, nullable=False)
- password = Column(String, nullable=False)
-
- # Required by sanic-beskar
- @property
- def rolenames(self):
- return []
-
- @classmethod
- async def lookup(cls, username=None):
- try:
- session = Session()
-
- user = session.query(UserDbModel).filter_by(username=username).first()
-
- session.close()
-
- return user
- except:
- return None
-
- @classmethod
- async def identify(cls, id):
- try:
- session = Session()
-
- user = session.query(UserDbModel).filter_by(id=id).first()
-
- session.close()
-
- return user
- except:
- return None
-
- @property
- def identity(self):
- return self.id
-
-
-Base.metadata.create_all(engine)
diff --git a/docker-compose.example.yml b/docker-compose.example.yml
new file mode 100644
index 00000000..a82e58e8
--- /dev/null
+++ b/docker-compose.example.yml
@@ -0,0 +1,15 @@
+services:
+ revanced-api:
+ container_name: revanced-api
+ image: ghcr.io/revanced/revanced-api:latest
+ volumes:
+ - /data/revanced-api/persistence:/app/persistence
+ - /data/revanced-api/.env:/app/.env
+ - /data/revanced-api/configuration.toml:/app/configuration.toml
+ - /data/revanced-api/patches-public-key.asc:/app/patches-public-key.asc
+ - /data/revanced-api/integrations-public-key.asc:/app/integrations-public-key.asc
+ environment:
+ - COMMAND=start
+ ports:
+ - 8888:8888
+ restart: unless-stopped
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index 02d487c4..00000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,16 +0,0 @@
-version: "3.8"
-
-services:
- revanced-api:
- container_name: revanced-api
- image: ghcr.io/revanced/revanced-api:latest
- volumes:
- - /data/revanced-api:/usr/src/app/persistence
- environment:
- - GITHUB_TOKEN=YOUR_GITHUB_TOKEN
- - SECRET_KEY=YOUR_SECRET_KEY
- - USERNAME=YOUR_USERNAME
- - PASSWORD=YOUR_PASSWORD
- ports:
- - 127.0.0.1:7934:8000
- restart: unless-stopped
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 00000000..dd50e336
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,4 @@
+org.gradle.parallel = true
+org.gradle.caching = true
+kotlin.code.style = official
+version = 1.0.0-dev.7
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
new file mode 100644
index 00000000..6730386a
--- /dev/null
+++ b/gradle/libs.versions.toml
@@ -0,0 +1,58 @@
+[versions]
+kompendium-core = "3.14.4"
+kotlin = "2.0.0"
+logback = "1.5.6"
+exposed = "0.52.0"
+h2 = "2.2.224"
+koin = "3.5.3"
+dotenv = "6.4.1"
+ktor = "2.3.7"
+ktoml = "0.5.2"
+picocli = "4.7.6"
+datetime = "0.6.0"
+revanced-patcher = "19.3.1"
+revanced-library = "2.3.0"
+caffeine = "3.1.8"
+bouncy-castle = "1.78.1"
+
+[libraries]
+kompendium-core = { module = "io.bkbn:kompendium-core", version.ref = "kompendium-core" }
+ktor-client-core = { module = "io.ktor:ktor-client-core" }
+ktor-client-cio = { module = "io.ktor:ktor-client-cio" }
+ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp" }
+ktor-client-resources = { module = "io.ktor:ktor-client-resources" }
+ktor-client-auth = { module = "io.ktor:ktor-client-auth" }
+ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation" }
+ktor-server-core = { module = "io.ktor:ktor-server-core" }
+ktor-server-content-negotiation = { module = "io.ktor:ktor-server-content-negotiation" }
+ktor-server-auth = { module = "io.ktor:ktor-server-auth" }
+ktor-server-auth-jwt = { module = "io.ktor:ktor-server-auth-jwt" }
+ktor-server-cors = { module = "io.ktor:ktor-server-cors" }
+ktor-server-caching-headers = { module = "io.ktor:ktor-server-caching-headers" }
+ktor-server-rate-limit = { module = "io.ktor:ktor-server-rate-limit" }
+ktor-server-host-common = { module = "io.ktor:ktor-server-host-common" }
+ktor-server-jetty = { module = "io.ktor:ktor-server-jetty" }
+ktor-server-call-logging = { module = "io.ktor:ktor-server-call-logging" }
+ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json" }
+koin-ktor = { module = "io.insert-koin:koin-ktor", version.ref = "koin" }
+h2 = { module = "com.h2database:h2", version.ref = "h2" }
+logback-classic = { module = "ch.qos.logback:logback-classic", version.ref = "logback" }
+exposed-core = { module = "org.jetbrains.exposed:exposed-core", version.ref = "exposed" }
+exposed-jdbc = { module = "org.jetbrains.exposed:exposed-jdbc", version.ref = "exposed" }
+exposed-dao = { module = "org.jetbrains.exposed:exposed-dao", version.ref = "exposed" }
+exposed-kotlin-datetime = { module = "org.jetbrains.exposed:exposed-kotlin-datetime", version.ref = "exposed" }
+dotenv-kotlin = { module = "io.github.cdimascio:dotenv-kotlin", version.ref = "dotenv" }
+ktoml-core = { module = "com.akuleshov7:ktoml-core", version.ref = "ktoml" }
+ktoml-file = { module = "com.akuleshov7:ktoml-file", version.ref = "ktoml" }
+picocli = { module = "info.picocli:picocli", version.ref = "picocli" }
+kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
+revanced-patcher = { module = "app.revanced:revanced-patcher", version.ref = "revanced-patcher" }
+revanced-library = { module = "app.revanced:revanced-library", version.ref = "revanced-library" }
+caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" }
+bouncy-castle-provider = { module = "org.bouncycastle:bcprov-jdk18on", version.ref = "bouncy-castle" }
+bouncy-castle-pgp = { module = "org.bouncycastle:bcpg-jdk18on", version.ref = "bouncy-castle" }
+
+[plugins]
+serilization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
+ktor = { id = "io.ktor.plugin", version.ref = "ktor" }
+kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..e6441136
Binary files /dev/null and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..8a1f6b97
--- /dev/null
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,8 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
new file mode 100755
index 00000000..b740cf13
--- /dev/null
+++ b/gradlew
@@ -0,0 +1,249 @@
+#!/bin/sh
+
+#
+# Copyright Š 2015-2021 the original authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions ÂĢ$varÂģ, ÂĢ${var}Âģ, ÂĢ${var:-default}Âģ, ÂĢ${var+SET}Âģ,
+# ÂĢ${var#prefix}Âģ, ÂĢ${var%suffix}Âģ, and ÂĢ$( cmd )Âģ;
+# * compound commands having a testable exit status, especially ÂĢcaseÂģ;
+# * various built-in commands including ÂĢcommandÂģ, ÂĢsetÂģ, and ÂĢulimitÂģ.
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
+##############################################################################
+
+# Attempt to set APP_HOME
+
+# Resolve links: $0 may be a link
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
+done
+
+# This is normally unused
+# shellcheck disable=SC2034
+APP_BASE_NAME=${0##*/}
+# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
+APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD=maximum
+
+warn () {
+ echo "$*"
+} >&2
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+} >&2
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD=$JAVA_HOME/jre/sh/java
+ else
+ JAVACMD=$JAVA_HOME/bin/java
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD=java
+ if ! command -v java >/dev/null 2>&1
+ then
+ die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+fi
+
+# Increase the maximum file descriptors if we can.
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
+ # shellcheck disable=SC2039,SC3045
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
+ esac
+fi
+
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Collect all arguments for the java command:
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
+# and any embedded shellness will be escaped.
+# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
+# treated as '${Hostname}' itself on the command line.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Stop when "xargs" is not available.
+if ! command -v xargs >/dev/null 2>&1
+then
+ die "xargs is not available"
+fi
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
+
+exec "$JAVACMD" "$@"
diff --git a/gradlew.bat b/gradlew.bat
new file mode 100755
index 00000000..25da30db
--- /dev/null
+++ b/gradlew.bat
@@ -0,0 +1,92 @@
+@rem
+@rem Copyright 2015 the original author or authors.
+@rem
+@rem Licensed under the Apache License, Version 2.0 (the "License");
+@rem you may not use this file except in compliance with the License.
+@rem You may obtain a copy of the License at
+@rem
+@rem https://www.apache.org/licenses/LICENSE-2.0
+@rem
+@rem Unless required by applicable law or agreed to in writing, software
+@rem distributed under the License is distributed on an "AS IS" BASIS,
+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@rem See the License for the specific language governing permissions and
+@rem limitations under the License.
+@rem
+
+@if "%DEBUG%"=="" @echo off
+@rem ##########################################################################
+@rem
+@rem Gradle startup script for Windows
+@rem
+@rem ##########################################################################
+
+@rem Set local scope for the variables with windows NT shell
+if "%OS%"=="Windows_NT" setlocal
+
+set DIRNAME=%~dp0
+if "%DIRNAME%"=="" set DIRNAME=.
+@rem This is normally unused
+set APP_BASE_NAME=%~n0
+set APP_HOME=%DIRNAME%
+
+@rem Resolve any "." and ".." in APP_HOME to make it shorter.
+for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
+
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
+
+@rem Find java.exe
+if defined JAVA_HOME goto findJavaFromJavaHome
+
+set JAVA_EXE=java.exe
+%JAVA_EXE% -version >NUL 2>&1
+if %ERRORLEVEL% equ 0 goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:findJavaFromJavaHome
+set JAVA_HOME=%JAVA_HOME:"=%
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
+
+if exist "%JAVA_EXE%" goto execute
+
+echo. 1>&2
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
+echo. 1>&2
+echo Please set the JAVA_HOME variable in your environment to match the 1>&2
+echo location of your Java installation. 1>&2
+
+goto fail
+
+:execute
+@rem Setup the command line
+
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
+
+
+@rem Execute Gradle
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
+
+:end
+@rem End local scope for the variables with windows NT shell
+if %ERRORLEVEL% equ 0 goto mainEnd
+
+:fail
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
+rem the _cmd.exe /c_ return code!
+set EXIT_CODE=%ERRORLEVEL%
+if %EXIT_CODE% equ 0 set EXIT_CODE=1
+if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
+exit /b %EXIT_CODE%
+
+:mainEnd
+if "%OS%"=="Windows_NT" endlocal
+
+:omega
diff --git a/mypy.ini b/mypy.ini
deleted file mode 100644
index 9009c162..00000000
--- a/mypy.ini
+++ /dev/null
@@ -1,30 +0,0 @@
-[mypy]
-python_version = 3.11
-pretty = true
-follow_imports = normal
-namespace_packages = true
-show_column_numbers = true
-show_error_codes = true
-allow_redefinition = false
-check_untyped_defs = true
-implicit_reexport = false
-strict_optional = true
-strict_equality = true
-warn_no_return = true
-warn_redundant_casts = true
-warn_unused_configs = true
-warn_unused_ignores = true
-warn_unreachable = true
-plugins = pydantic.mypy
-
-[mypy-toolz.*]
-ignore_missing_imports = True
-
-[mypy-sanic_testing.*]
-ignore_missing_imports = True
-
-[mypy-fire.*]
-ignore_missing_imports = True
-
-[mypy-cytoolz.*]
-ignore_missing_imports = True
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..29e79ed2
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,6895 @@
+{
+ "name": "revanced-patches",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "devDependencies": {
+ "@saithodev/semantic-release-backmerge": "^4.0.1",
+ "@semantic-release/changelog": "^6.0.3",
+ "@semantic-release/git": "^10.0.1",
+ "gradle-semantic-release-plugin": "^1.9.1",
+ "semantic-release": "^23.0.0"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.23.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz",
+ "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/highlight": "^7.23.4",
+ "chalk": "^2.4.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/code-frame/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.22.20",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
+ "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight": {
+ "version": "7.23.4",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz",
+ "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==",
+ "dev": true,
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.22.20",
+ "chalk": "^2.4.2",
+ "js-tokens": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/@babel/highlight/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@babel/highlight/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/@nodelib/fs.scandir": {
+ "version": "2.1.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
+ "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "2.0.5",
+ "run-parallel": "^1.1.9"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.stat": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
+ "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@nodelib/fs.walk": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
+ "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.scandir": "2.1.5",
+ "fastq": "^1.6.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/@octokit/auth-token": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-4.0.0.tgz",
+ "integrity": "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/core": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/core/-/core-5.1.0.tgz",
+ "integrity": "sha512-BDa2VAMLSh3otEiaMJ/3Y36GU4qf6GI+VivQ/P41NC6GHcdxpKlqV0ikSZ5gdQsmS3ojXeRx5vasgNTinF0Q4g==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/auth-token": "^4.0.0",
+ "@octokit/graphql": "^7.0.0",
+ "@octokit/request": "^8.0.2",
+ "@octokit/request-error": "^5.0.0",
+ "@octokit/types": "^12.0.0",
+ "before-after-hook": "^2.2.0",
+ "universal-user-agent": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/endpoint": {
+ "version": "9.0.4",
+ "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-9.0.4.tgz",
+ "integrity": "sha512-DWPLtr1Kz3tv8L0UvXTDP1fNwM0S+z6EJpRcvH66orY6Eld4XBMCSYsaWp4xIm61jTWxK68BrR7ibO+vSDnZqw==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^12.0.0",
+ "universal-user-agent": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/graphql": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-7.0.2.tgz",
+ "integrity": "sha512-OJ2iGMtj5Tg3s6RaXH22cJcxXRi7Y3EBqbHTBRq+PQAqfaS8f/236fUrWhfSn8P4jovyzqucxme7/vWSSZBX2Q==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/request": "^8.0.1",
+ "@octokit/types": "^12.0.0",
+ "universal-user-agent": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/openapi-types": {
+ "version": "19.1.0",
+ "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-19.1.0.tgz",
+ "integrity": "sha512-6G+ywGClliGQwRsjvqVYpklIfa7oRPA0vyhPQG/1Feh+B+wU0vGH1JiJ5T25d3g1JZYBHzR2qefLi9x8Gt+cpw==",
+ "dev": true
+ },
+ "node_modules/@octokit/plugin-paginate-rest": {
+ "version": "9.1.5",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.1.5.tgz",
+ "integrity": "sha512-WKTQXxK+bu49qzwv4qKbMMRXej1DU2gq017euWyKVudA6MldaSSQuxtz+vGbhxV4CjxpUxjZu6rM2wfc1FiWVg==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^12.4.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@octokit/core": ">=5"
+ }
+ },
+ "node_modules/@octokit/plugin-retry": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-retry/-/plugin-retry-6.0.1.tgz",
+ "integrity": "sha512-SKs+Tz9oj0g4p28qkZwl/topGcb0k0qPNX/i7vBKmDsjoeqnVfFUquqrE/O9oJY7+oLzdCtkiWSXLpLjvl6uog==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/request-error": "^5.0.0",
+ "@octokit/types": "^12.0.0",
+ "bottleneck": "^2.15.3"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@octokit/core": ">=5"
+ }
+ },
+ "node_modules/@octokit/plugin-throttling": {
+ "version": "8.1.3",
+ "resolved": "https://registry.npmjs.org/@octokit/plugin-throttling/-/plugin-throttling-8.1.3.tgz",
+ "integrity": "sha512-pfyqaqpc0EXh5Cn4HX9lWYsZ4gGbjnSmUILeu4u2gnuM50K/wIk9s1Pxt3lVeVwekmITgN/nJdoh43Ka+vye8A==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^12.2.0",
+ "bottleneck": "^2.15.3"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@octokit/core": "^5.0.0"
+ }
+ },
+ "node_modules/@octokit/request": {
+ "version": "8.1.6",
+ "resolved": "https://registry.npmjs.org/@octokit/request/-/request-8.1.6.tgz",
+ "integrity": "sha512-YhPaGml3ncZC1NfXpP3WZ7iliL1ap6tLkAp6MvbK2fTTPytzVUyUesBBogcdMm86uRYO5rHaM1xIWxigWZ17MQ==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/endpoint": "^9.0.0",
+ "@octokit/request-error": "^5.0.0",
+ "@octokit/types": "^12.0.0",
+ "universal-user-agent": "^6.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/request-error": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-5.0.1.tgz",
+ "integrity": "sha512-X7pnyTMV7MgtGmiXBwmO6M5kIPrntOXdyKZLigNfQWSEQzVxR4a4vo49vJjTWX70mPndj8KhfT4Dx+2Ng3vnBQ==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/types": "^12.0.0",
+ "deprecation": "^2.0.0",
+ "once": "^1.4.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/@octokit/types": {
+ "version": "12.4.0",
+ "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.4.0.tgz",
+ "integrity": "sha512-FLWs/AvZllw/AGVs+nJ+ELCDZZJk+kY0zMen118xhL2zD0s1etIUHm1odgjP7epxYU1ln7SZxEUWYop5bhsdgQ==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/openapi-types": "^19.1.0"
+ }
+ },
+ "node_modules/@pnpm/config.env-replace": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@pnpm/config.env-replace/-/config.env-replace-1.1.0.tgz",
+ "integrity": "sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz",
+ "integrity": "sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "4.2.10"
+ },
+ "engines": {
+ "node": ">=12.22.0"
+ }
+ },
+ "node_modules/@pnpm/network.ca-file/node_modules/graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
+ "dev": true
+ },
+ "node_modules/@pnpm/npm-conf": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/@pnpm/npm-conf/-/npm-conf-2.2.2.tgz",
+ "integrity": "sha512-UA91GwWPhFExt3IizW6bOeY/pQ0BkuNwKjk9iQW9KqxluGCrg4VenZ0/L+2Y0+ZOtme72EVvg6v0zo3AMQRCeA==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/config.env-replace": "^1.1.0",
+ "@pnpm/network.ca-file": "^1.0.1",
+ "config-chain": "^1.1.11"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/@saithodev/semantic-release-backmerge/-/semantic-release-backmerge-4.0.1.tgz",
+ "integrity": "sha512-WDsU28YrXSLx0xny7FgFlEk8DCKGcj6OOhA+4Q9k3te1jJD1GZuqY8sbIkVQaw9cqJ7CT+fCZUN6QDad8JW4Dg==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/error": "^3.0.0",
+ "aggregate-error": "^3.1.0",
+ "debug": "^4.3.4",
+ "execa": "^5.1.1",
+ "lodash": "^4.17.21",
+ "semantic-release": "^22.0.7"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/clean-stack": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz",
+ "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "5.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/cosmiconfig": {
+ "version": "8.3.6",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
+ "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
+ "dev": true,
+ "dependencies": {
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0",
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-10.0.0.tgz",
+ "integrity": "sha512-U4xcd/utDYFgMh0yWj07R1H6L5fwhVbmxBCpnL0DbVSDZVnsC82HONw0wxtxNkIAcua3KtbomQvIk5xFZGAQJw==",
+ "dev": true,
+ "dependencies": {
+ "execa": "^8.0.0",
+ "java-properties": "^1.0.2"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/env-ci/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/marked": {
+ "version": "9.1.6",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz",
+ "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/npm-run-path": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
+ "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/p-reduce": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz",
+ "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release": {
+ "version": "22.0.12",
+ "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-22.0.12.tgz",
+ "integrity": "sha512-0mhiCR/4sZb00RVFJIUlMuiBkW3NMpVIW2Gse7noqEMoFGkvfPPAImEQbkBV8xga4KOPP4FdTRYuLLy32R1fPw==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/commit-analyzer": "^11.0.0",
+ "@semantic-release/error": "^4.0.0",
+ "@semantic-release/github": "^9.0.0",
+ "@semantic-release/npm": "^11.0.0",
+ "@semantic-release/release-notes-generator": "^12.0.0",
+ "aggregate-error": "^5.0.0",
+ "cosmiconfig": "^8.0.0",
+ "debug": "^4.0.0",
+ "env-ci": "^10.0.0",
+ "execa": "^8.0.0",
+ "figures": "^6.0.0",
+ "find-versions": "^5.1.0",
+ "get-stream": "^6.0.0",
+ "git-log-parser": "^1.2.0",
+ "hook-std": "^3.0.0",
+ "hosted-git-info": "^7.0.0",
+ "import-from-esm": "^1.3.1",
+ "lodash-es": "^4.17.21",
+ "marked": "^9.0.0",
+ "marked-terminal": "^6.0.0",
+ "micromatch": "^4.0.2",
+ "p-each-series": "^3.0.0",
+ "p-reduce": "^3.0.0",
+ "read-pkg-up": "^11.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.3.2",
+ "semver-diff": "^4.0.0",
+ "signale": "^1.2.1",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "semantic-release": "bin/semantic-release.js"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/@semantic-release/error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz",
+ "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/aggregate-error": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz",
+ "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^5.2.0",
+ "indent-string": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/semantic-release/node_modules/execa/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@saithodev/semantic-release-backmerge/node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/changelog": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz",
+ "integrity": "sha512-dZuR5qByyfe3Y03TpmCvAxCyTnp7r5XwtHRf/8vD9EAn4ZWbavUX8adMtXYzE86EVh0gyLA7lm5yW4IV30XUag==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/error": "^3.0.0",
+ "aggregate-error": "^3.0.0",
+ "fs-extra": "^11.0.0",
+ "lodash": "^4.17.4"
+ },
+ "engines": {
+ "node": ">=14.17"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=18.0.0"
+ }
+ },
+ "node_modules/@semantic-release/commit-analyzer": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-11.1.0.tgz",
+ "integrity": "sha512-cXNTbv3nXR2hlzHjAMgbuiQVtvWHTlwwISt60B+4NZv01y/QRY7p2HcJm8Eh2StzcTJoNnflvKjHH/cjFS7d5g==",
+ "dev": true,
+ "dependencies": {
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "debug": "^4.0.0",
+ "import-from-esm": "^1.0.3",
+ "lodash-es": "^4.17.21",
+ "micromatch": "^4.0.2"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/error": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-3.0.0.tgz",
+ "integrity": "sha512-5hiM4Un+tpl4cKw3lV4UgzJj+SmfNIDCLLw0TepzQxz9ZGV5ixnqkzIVF+3tp0ZHgcMKE+VNGHJjEeyFG2dcSw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@semantic-release/git": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/@semantic-release/git/-/git-10.0.1.tgz",
+ "integrity": "sha512-eWrx5KguUcU2wUPaO6sfvZI0wPafUKAMNC18aXY4EnNcrZL86dEmpNVnC9uMpGZkmZJ9EfCVJBQx4pV4EMGT1w==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/error": "^3.0.0",
+ "aggregate-error": "^3.0.0",
+ "debug": "^4.0.0",
+ "dir-glob": "^3.0.0",
+ "execa": "^5.0.0",
+ "lodash": "^4.17.4",
+ "micromatch": "^4.0.0",
+ "p-reduce": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.17"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=18.0.0"
+ }
+ },
+ "node_modules/@semantic-release/github": {
+ "version": "9.2.6",
+ "resolved": "https://registry.npmjs.org/@semantic-release/github/-/github-9.2.6.tgz",
+ "integrity": "sha512-shi+Lrf6exeNZF+sBhK+P011LSbhmIAoUEgEY6SsxF8irJ+J2stwI5jkyDQ+4gzYyDImzV6LCKdYB9FXnQRWKA==",
+ "dev": true,
+ "dependencies": {
+ "@octokit/core": "^5.0.0",
+ "@octokit/plugin-paginate-rest": "^9.0.0",
+ "@octokit/plugin-retry": "^6.0.0",
+ "@octokit/plugin-throttling": "^8.0.0",
+ "@semantic-release/error": "^4.0.0",
+ "aggregate-error": "^5.0.0",
+ "debug": "^4.3.4",
+ "dir-glob": "^3.0.1",
+ "globby": "^14.0.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.0",
+ "issue-parser": "^6.0.0",
+ "lodash-es": "^4.17.21",
+ "mime": "^4.0.0",
+ "p-filter": "^4.0.0",
+ "url-join": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/@semantic-release/error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz",
+ "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/aggregate-error": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz",
+ "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^5.2.0",
+ "indent-string": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/clean-stack": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz",
+ "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "5.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/github/node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm": {
+ "version": "11.0.2",
+ "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-11.0.2.tgz",
+ "integrity": "sha512-owtf3RjyPvRE63iUKZ5/xO4uqjRpVQDUB9+nnXj0xwfIeM9pRl+cG+zGDzdftR4m3f2s4Wyf3SexW+kF5DFtWA==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/error": "^4.0.0",
+ "aggregate-error": "^5.0.0",
+ "execa": "^8.0.0",
+ "fs-extra": "^11.0.0",
+ "lodash-es": "^4.17.21",
+ "nerf-dart": "^1.0.0",
+ "normalize-url": "^8.0.0",
+ "npm": "^10.0.0",
+ "rc": "^1.2.8",
+ "read-pkg": "^9.0.0",
+ "registry-auth-token": "^5.0.0",
+ "semver": "^7.1.2",
+ "tempy": "^3.0.0"
+ },
+ "engines": {
+ "node": "^18.17 || >=20"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/@semantic-release/error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz",
+ "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/aggregate-error": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz",
+ "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^5.2.0",
+ "indent-string": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/clean-stack": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz",
+ "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "5.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/npm-run-path": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
+ "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@semantic-release/npm/node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@semantic-release/release-notes-generator": {
+ "version": "12.1.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-12.1.0.tgz",
+ "integrity": "sha512-g6M9AjUKAZUZnxaJZnouNBeDNTCUrJ5Ltj+VJ60gJeDaRRahcHsry9HW8yKrnKkKNkx5lbWiEP1FPMqVNQz8Kg==",
+ "dev": true,
+ "dependencies": {
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-changelog-writer": "^7.0.0",
+ "conventional-commits-filter": "^4.0.0",
+ "conventional-commits-parser": "^5.0.0",
+ "debug": "^4.0.0",
+ "get-stream": "^7.0.0",
+ "import-from-esm": "^1.0.3",
+ "into-stream": "^7.0.0",
+ "lodash-es": "^4.17.21",
+ "read-pkg-up": "^11.0.0"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ },
+ "peerDependencies": {
+ "semantic-release": ">=20.1.0"
+ }
+ },
+ "node_modules/@semantic-release/release-notes-generator/node_modules/get-stream": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-7.0.1.tgz",
+ "integrity": "sha512-3M8C1EOFN6r8AMUhwUAACIoXZJEOufDU5+0gFFN5uNs6XYOralD2Pqkl7m046va6x77FwposWXbAhPPIOus7mQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+ "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@sindresorhus/merge-streams": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-1.0.0.tgz",
+ "integrity": "sha512-rUV5WyJrJLoloD4NDN1V1+LDMDWOa4OTsT4yYJwQNpTU6FWxkxHpL7eu4w+DmiH8x/EAM1otkPE1+LaspIbplw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@types/normalize-package-data": {
+ "version": "2.4.4",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz",
+ "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==",
+ "dev": true
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz",
+ "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
+ "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-escapes": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.0.tgz",
+ "integrity": "sha512-kzRaCqXnpzWs+3z5ABPQiVke+iq0KXkHo8xiWV4RPTi5Yli0l97BEQuhXV1s7+aSU/fu1kUuxgS4MsQ0fRuygw==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansicolors": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.3.2.tgz",
+ "integrity": "sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==",
+ "dev": true
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true
+ },
+ "node_modules/argv-formatter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/argv-formatter/-/argv-formatter-1.0.0.tgz",
+ "integrity": "sha512-F2+Hkm9xFaRg+GkaNnbwXNDV5O6pnCFEmqyhvfC/Ic5LbgOWjJh3L+mN/s91rxVL3znE7DYVpW0GJFT+4YBgWw==",
+ "dev": true
+ },
+ "node_modules/array-ify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
+ "dev": true
+ },
+ "node_modules/before-after-hook": {
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz",
+ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==",
+ "dev": true
+ },
+ "node_modules/bottleneck": {
+ "version": "2.19.5",
+ "resolved": "https://registry.npmjs.org/bottleneck/-/bottleneck-2.19.5.tgz",
+ "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==",
+ "dev": true
+ },
+ "node_modules/braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "dependencies": {
+ "fill-range": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cardinal": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-2.1.1.tgz",
+ "integrity": "sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==",
+ "dev": true,
+ "dependencies": {
+ "ansicolors": "~0.3.2",
+ "redeyed": "~2.1.0"
+ },
+ "bin": {
+ "cdl": "bin/cdl.js"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz",
+ "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==",
+ "dev": true,
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.3.tgz",
+ "integrity": "sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true
+ },
+ "node_modules/compare-func": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
+ "dev": true,
+ "dependencies": {
+ "array-ify": "^1.0.0",
+ "dot-prop": "^5.1.0"
+ }
+ },
+ "node_modules/config-chain": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
+ "dev": true,
+ "dependencies": {
+ "ini": "^1.3.4",
+ "proto-list": "~1.2.1"
+ }
+ },
+ "node_modules/conventional-changelog-angular": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
+ "dev": true,
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-changelog-writer": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz",
+ "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==",
+ "dev": true,
+ "dependencies": {
+ "conventional-commits-filter": "^4.0.0",
+ "handlebars": "^4.7.7",
+ "json-stringify-safe": "^5.0.1",
+ "meow": "^12.0.1",
+ "semver": "^7.5.2",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "conventional-changelog-writer": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-commits-filter": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz",
+ "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-commits-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
+ "dev": true,
+ "dependencies": {
+ "is-text-path": "^2.0.0",
+ "JSONStream": "^1.3.5",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "conventional-commits-parser": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/core-util-is": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
+ "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
+ "dev": true
+ },
+ "node_modules/cosmiconfig": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz",
+ "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==",
+ "dev": true,
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/crypto-random-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz",
+ "integrity": "sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==",
+ "dev": true,
+ "dependencies": {
+ "type-fest": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/crypto-random-string/node_modules/type-fest": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz",
+ "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0.0"
+ }
+ },
+ "node_modules/deprecation": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz",
+ "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==",
+ "dev": true
+ },
+ "node_modules/dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "dependencies": {
+ "path-type": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/duplexer2": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
+ "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "node_modules/emojilib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz",
+ "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==",
+ "dev": true
+ },
+ "node_modules/env-ci": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/env-ci/-/env-ci-11.0.0.tgz",
+ "integrity": "sha512-apikxMgkipkgTvMdRT9MNqWx5VLOci79F4VBd7Op/7OPjjoanjdAvn6fglMCCEf/1bAh8eOiuEVCUs4V3qP3nQ==",
+ "dev": true,
+ "dependencies": {
+ "execa": "^8.0.0",
+ "java-properties": "^1.0.2"
+ },
+ "engines": {
+ "node": "^18.17 || >=20.6.1"
+ }
+ },
+ "node_modules/env-ci/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/env-ci/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/env-ci/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/npm-run-path": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
+ "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-ci/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/env-ci/node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "dev": true,
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true,
+ "bin": {
+ "esparse": "bin/esparse.js",
+ "esvalidate": "bin/esvalidate.js"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/fast-glob": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
+ "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
+ "dev": true,
+ "dependencies": {
+ "@nodelib/fs.stat": "^2.0.2",
+ "@nodelib/fs.walk": "^1.2.3",
+ "glob-parent": "^5.1.2",
+ "merge2": "^1.3.0",
+ "micromatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=8.6.0"
+ }
+ },
+ "node_modules/fastq": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.16.0.tgz",
+ "integrity": "sha512-ifCoaXsDrsdkWTtiNJX5uzHDsrck5TzfKKDcuFFTIrrc/BS076qgEIfoIy1VeZqViznfKiysPYTh/QeHtnIsYA==",
+ "dev": true,
+ "dependencies": {
+ "reusify": "^1.0.4"
+ }
+ },
+ "node_modules/figures": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.0.1.tgz",
+ "integrity": "sha512-0oY/olScYD4IhQ8u//gCPA4F3mlTn2dacYmiDm/mbDQvpmLjV4uH+zhsQ5IyXRyvqkvtUkXkNdGvg5OFJTCsuQ==",
+ "dev": true,
+ "dependencies": {
+ "is-unicode-supported": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "dependencies": {
+ "to-regex-range": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/find-up-simple": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/find-up-simple/-/find-up-simple-1.0.0.tgz",
+ "integrity": "sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/find-versions": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz",
+ "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==",
+ "dev": true,
+ "dependencies": {
+ "semver-regex": "^4.0.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==",
+ "dev": true,
+ "dependencies": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "node_modules/fs-extra": {
+ "version": "11.2.0",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
+ "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=14.14"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/git-log-parser": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/git-log-parser/-/git-log-parser-1.2.0.tgz",
+ "integrity": "sha512-rnCVNfkTL8tdNryFuaY0fYiBWEBcgF748O6ZI61rslBvr2o7U65c2/6npCRqH40vuAhtgtDiqLTJjBVdrejCzA==",
+ "dev": true,
+ "dependencies": {
+ "argv-formatter": "~1.0.0",
+ "spawn-error-forwarder": "~1.0.0",
+ "split2": "~1.0.0",
+ "stream-combiner2": "~1.1.1",
+ "through2": "~2.0.0",
+ "traverse": "~0.6.6"
+ }
+ },
+ "node_modules/git-log-parser/node_modules/split2": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-1.0.0.tgz",
+ "integrity": "sha512-NKywug4u4pX/AZBB1FCPzZ6/7O+Xhz1qMVbzTvvKvikjO99oPN87SkK08mEY9P63/5lWjK+wgOOgApnTg5r6qg==",
+ "dev": true,
+ "dependencies": {
+ "through2": "~2.0.0"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
+ "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
+ "dev": true,
+ "dependencies": {
+ "is-glob": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/globby": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.0.tgz",
+ "integrity": "sha512-/1WM/LNHRAOH9lZta77uGbq0dAEQM+XjNesWwhlERDVenqothRbnzTrL3/LrIoEPPjeUHC3vrS6TwoyxeHs7MQ==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/merge-streams": "^1.0.0",
+ "fast-glob": "^3.3.2",
+ "ignore": "^5.2.4",
+ "path-type": "^5.0.0",
+ "slash": "^5.1.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globby/node_modules/path-type": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
+ "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
+ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
+ "dev": true
+ },
+ "node_modules/gradle-semantic-release-plugin": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/gradle-semantic-release-plugin/-/gradle-semantic-release-plugin-1.9.1.tgz",
+ "integrity": "sha512-lCrw22itszP/FLSL3N61E40vH1+CU95/4LG9ZF+Fxr8tcx7EPthh2eqVPAq67udFlM8ZgO2LETnn8LSDRq1J2w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/KengoTODA"
+ }
+ ],
+ "dependencies": {
+ "promisified-properties": "^3.0.0",
+ "split2": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "peerDependencies": {
+ "semantic-release": "^23.0.0"
+ }
+ },
+ "node_modules/handlebars": {
+ "version": "4.7.8",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz",
+ "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==",
+ "dev": true,
+ "dependencies": {
+ "minimist": "^1.2.5",
+ "neo-async": "^2.6.2",
+ "source-map": "^0.6.1",
+ "wordwrap": "^1.0.0"
+ },
+ "bin": {
+ "handlebars": "bin/handlebars"
+ },
+ "engines": {
+ "node": ">=0.4.7"
+ },
+ "optionalDependencies": {
+ "uglify-js": "^3.1.4"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz",
+ "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==",
+ "dev": true,
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/hook-std": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/hook-std/-/hook-std-3.0.0.tgz",
+ "integrity": "sha512-jHRQzjSDzMtFy34AGj1DN+vq54WVuhSvKgrHf0OMiFQTwDD4L/qqofVEWjLOBMTn5+lCD3fPg32W9yOfnEJTTw==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/hosted-git-info": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.1.tgz",
+ "integrity": "sha512-+K84LB1DYwMHoHSgaOY/Jfhw3ucPmSET5v98Ke/HdNSw4a0UktWzyW1mjhjpuxxTqOOsfWT/7iVshHmVZ4IpOA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/http-proxy-agent": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz",
+ "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz",
+ "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==",
+ "dev": true,
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=10.17.0"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz",
+ "integrity": "sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+ "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+ "dev": true,
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-fresh/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-from-esm": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/import-from-esm/-/import-from-esm-1.3.3.tgz",
+ "integrity": "sha512-U3Qt/CyfFpTUv6LOP2jRTLYjphH6zg3okMfHbyqRa/W2w6hr8OsJWVggNlR4jxuojQy81TgTJTxgSkyoteRGMQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "import-meta-resolve": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.20"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz",
+ "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/indent-string": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
+ "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/index-to-position": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/index-to-position/-/index-to-position-0.1.2.tgz",
+ "integrity": "sha512-MWDKS3AS1bGCHLBA2VLImJz42f7bJh8wQsTGCzI3j519/CASStoDONUBVz2I/VID0MpiX3SGSnbOD2xUalbE5g==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "dev": true
+ },
+ "node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
+ "node_modules/into-stream": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/into-stream/-/into-stream-7.0.0.tgz",
+ "integrity": "sha512-2dYz766i9HprMBasCMvHMuazJ7u4WzhJwo5kb3iPSiW/iRYV6uPari3zHoqZlnuaR7V1bEiNMxikhp37rdBXbw==",
+ "dev": true,
+ "dependencies": {
+ "from2": "^2.3.0",
+ "p-is-promise": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true
+ },
+ "node_modules/is-core-module": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz",
+ "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==",
+ "dev": true,
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.12.0"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-unicode-supported": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.0.0.tgz",
+ "integrity": "sha512-FRdAyx5lusK1iHG0TWpVtk9+1i+GjrzRffhDg4ovQ7mcidMQ6mj+MhKPmvh7Xwyv5gIS06ns49CA7Sqg7lC22Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
+ "dev": true
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true
+ },
+ "node_modules/issue-parser": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/issue-parser/-/issue-parser-6.0.0.tgz",
+ "integrity": "sha512-zKa/Dxq2lGsBIXQ7CUZWTHfvxPC2ej0KfO7fIPqLlHB9J2hJ7rGhZ5rilhuufylr4RXYPzJUeFjKxz305OsNlA==",
+ "dev": true,
+ "dependencies": {
+ "lodash.capitalize": "^4.2.1",
+ "lodash.escaperegexp": "^4.1.2",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.uniqby": "^4.7.0"
+ },
+ "engines": {
+ "node": ">=10.13"
+ }
+ },
+ "node_modules/java-properties": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/java-properties/-/java-properties-1.0.2.tgz",
+ "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
+ "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
+ "dev": true,
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true
+ },
+ "node_modules/json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
+ "dev": true
+ },
+ "node_modules/jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "dev": true,
+ "dependencies": {
+ "universalify": "^2.0.0"
+ },
+ "optionalDependencies": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ]
+ },
+ "node_modules/JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ },
+ "bin": {
+ "JSONStream": "bin.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true
+ },
+ "node_modules/load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==",
+ "dev": true,
+ "dependencies": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/load-json-file/node_modules/parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==",
+ "dev": true,
+ "dependencies": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
+ "dev": true
+ },
+ "node_modules/lodash-es": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
+ "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
+ "dev": true
+ },
+ "node_modules/lodash.capitalize": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz",
+ "integrity": "sha512-kZzYOKspf8XVX5AvmQF94gQW0lejFVgb80G85bU4ZWzoJ6C03PQg3coYAUpSTpQWelrZELd3XWgHzw4Ck5kaIw==",
+ "dev": true
+ },
+ "node_modules/lodash.escaperegexp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
+ "integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==",
+ "dev": true
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true
+ },
+ "node_modules/lodash.isstring": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
+ "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==",
+ "dev": true
+ },
+ "node_modules/lodash.uniqby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz",
+ "integrity": "sha512-e/zcLx6CSbmaEgFHCA7BnoQKyCtKMxnuWrJygbwPs/AIn+IMKl66L8/s+wBUn5LRw2pZx3bUHibiV1b6aTWIww==",
+ "dev": true
+ },
+ "node_modules/lru-cache": {
+ "version": "10.2.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz",
+ "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==",
+ "dev": true,
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/marked": {
+ "version": "11.1.1",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-11.1.1.tgz",
+ "integrity": "sha512-EgxRjgK9axsQuUa/oKMx5DEY8oXpKJfk61rT5iY3aRlgU6QJtUcxU5OAymdhCvWvhYcd9FKmO5eQoX8m9VGJXg==",
+ "dev": true,
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/marked-terminal": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-6.2.0.tgz",
+ "integrity": "sha512-ubWhwcBFHnXsjYNsu+Wndpg0zhY4CahSpPlA70PlO0rR9r2sZpkyU+rkCsOWH+KMEkx847UpALON+HWgxowFtw==",
+ "dev": true,
+ "dependencies": {
+ "ansi-escapes": "^6.2.0",
+ "cardinal": "^2.1.1",
+ "chalk": "^5.3.0",
+ "cli-table3": "^0.6.3",
+ "node-emoji": "^2.1.3",
+ "supports-hyperlinks": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "marked": ">=1 <12"
+ }
+ },
+ "node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
+ "dev": true
+ },
+ "node_modules/merge2": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
+ "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "dev": true,
+ "dependencies": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ },
+ "engines": {
+ "node": ">=8.6"
+ }
+ },
+ "node_modules/mime": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-4.0.1.tgz",
+ "integrity": "sha512-5lZ5tyrIfliMXzFtkYyekWbtRXObT9OWa8IwQ5uxTBDHucNNwniRqo0yInflj+iYi5CBa6qxadGzGarDfuEOxA==",
+ "dev": true,
+ "funding": [
+ "https://github.com/sponsors/broofa"
+ ],
+ "bin": {
+ "mime": "bin/cli.js"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/neo-async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
+ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
+ "dev": true
+ },
+ "node_modules/nerf-dart": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/nerf-dart/-/nerf-dart-1.0.0.tgz",
+ "integrity": "sha512-EZSPZB70jiVsivaBLYDCyntd5eH8NTSMOn3rB+HxwdmKThGELLdYv8qVIMWvZEFy9w8ZZpW9h9OB32l1rGtj7g==",
+ "dev": true
+ },
+ "node_modules/node-emoji": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.1.3.tgz",
+ "integrity": "sha512-E2WEOVsgs7O16zsURJ/eH8BqhF029wGpEOnv7Urwdo2wmQanOACwJQh0devF9D9RhoZru0+9JXIS0dBXIAz+lA==",
+ "dev": true,
+ "dependencies": {
+ "@sindresorhus/is": "^4.6.0",
+ "char-regex": "^1.0.2",
+ "emojilib": "^2.4.0",
+ "skin-tone": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/normalize-package-data": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.0.tgz",
+ "integrity": "sha512-UL7ELRVxYBHBgYEtZCXjxuD5vPxnmvMGq0jp/dGPKKrN7tfsBh2IY7TlJ15WWwdjRWD3RJbnsygUurTK3xkPkg==",
+ "dev": true,
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/normalize-url": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz",
+ "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/npm/-/npm-10.4.0.tgz",
+ "integrity": "sha512-RS7Mx0OVfXlOcQLRePuDIYdFCVBPCNapWHplDK+mh7GDdP/Tvor4ocuybRRPSvfcRb2vjRJt1fHCqw3cr8qACQ==",
+ "bundleDependencies": [
+ "@isaacs/string-locale-compare",
+ "@npmcli/arborist",
+ "@npmcli/config",
+ "@npmcli/fs",
+ "@npmcli/map-workspaces",
+ "@npmcli/package-json",
+ "@npmcli/promise-spawn",
+ "@npmcli/run-script",
+ "@sigstore/tuf",
+ "abbrev",
+ "archy",
+ "cacache",
+ "chalk",
+ "ci-info",
+ "cli-columns",
+ "cli-table3",
+ "columnify",
+ "fastest-levenshtein",
+ "fs-minipass",
+ "glob",
+ "graceful-fs",
+ "hosted-git-info",
+ "ini",
+ "init-package-json",
+ "is-cidr",
+ "json-parse-even-better-errors",
+ "libnpmaccess",
+ "libnpmdiff",
+ "libnpmexec",
+ "libnpmfund",
+ "libnpmhook",
+ "libnpmorg",
+ "libnpmpack",
+ "libnpmpublish",
+ "libnpmsearch",
+ "libnpmteam",
+ "libnpmversion",
+ "make-fetch-happen",
+ "minimatch",
+ "minipass",
+ "minipass-pipeline",
+ "ms",
+ "node-gyp",
+ "nopt",
+ "normalize-package-data",
+ "npm-audit-report",
+ "npm-install-checks",
+ "npm-package-arg",
+ "npm-pick-manifest",
+ "npm-profile",
+ "npm-registry-fetch",
+ "npm-user-validate",
+ "npmlog",
+ "p-map",
+ "pacote",
+ "parse-conflict-json",
+ "proc-log",
+ "qrcode-terminal",
+ "read",
+ "semver",
+ "spdx-expression-parse",
+ "ssri",
+ "supports-color",
+ "tar",
+ "text-table",
+ "tiny-relative-date",
+ "treeverse",
+ "validate-npm-package-name",
+ "which",
+ "write-file-atomic"
+ ],
+ "dev": true,
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/config": "^8.0.2",
+ "@npmcli/fs": "^3.1.0",
+ "@npmcli/map-workspaces": "^3.0.4",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.1",
+ "@npmcli/run-script": "^7.0.4",
+ "@sigstore/tuf": "^2.3.0",
+ "abbrev": "^2.0.0",
+ "archy": "~1.0.0",
+ "cacache": "^18.0.2",
+ "chalk": "^5.3.0",
+ "ci-info": "^4.0.0",
+ "cli-columns": "^4.0.0",
+ "cli-table3": "^0.6.3",
+ "columnify": "^1.6.0",
+ "fastest-levenshtein": "^1.0.16",
+ "fs-minipass": "^3.0.3",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.11",
+ "hosted-git-info": "^7.0.1",
+ "ini": "^4.1.1",
+ "init-package-json": "^6.0.0",
+ "is-cidr": "^5.0.3",
+ "json-parse-even-better-errors": "^3.0.1",
+ "libnpmaccess": "^8.0.1",
+ "libnpmdiff": "^6.0.3",
+ "libnpmexec": "^7.0.4",
+ "libnpmfund": "^5.0.1",
+ "libnpmhook": "^10.0.0",
+ "libnpmorg": "^6.0.1",
+ "libnpmpack": "^6.0.3",
+ "libnpmpublish": "^9.0.2",
+ "libnpmsearch": "^7.0.0",
+ "libnpmteam": "^6.0.0",
+ "libnpmversion": "^5.0.1",
+ "make-fetch-happen": "^13.0.0",
+ "minimatch": "^9.0.3",
+ "minipass": "^7.0.4",
+ "minipass-pipeline": "^1.2.4",
+ "ms": "^2.1.2",
+ "node-gyp": "^10.0.1",
+ "nopt": "^7.2.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-audit-report": "^5.0.0",
+ "npm-install-checks": "^6.3.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-profile": "^9.0.0",
+ "npm-registry-fetch": "^16.1.0",
+ "npm-user-validate": "^2.0.0",
+ "npmlog": "^7.0.1",
+ "p-map": "^4.0.0",
+ "pacote": "^17.0.6",
+ "parse-conflict-json": "^3.0.1",
+ "proc-log": "^3.0.0",
+ "qrcode-terminal": "^0.12.0",
+ "read": "^2.1.0",
+ "semver": "^7.5.4",
+ "spdx-expression-parse": "^3.0.1",
+ "ssri": "^10.0.5",
+ "supports-color": "^9.4.0",
+ "tar": "^6.2.0",
+ "text-table": "~0.2.0",
+ "tiny-relative-date": "^1.3.0",
+ "treeverse": "^3.0.0",
+ "validate-npm-package-name": "^5.0.0",
+ "which": "^4.0.0",
+ "write-file-atomic": "^5.0.1"
+ },
+ "bin": {
+ "npm": "bin/npm-cli.js",
+ "npx": "bin/npx-cli.js"
+ },
+ "engines": {
+ "node": "^18.17.0 || >=20.5.0"
+ }
+ },
+ "node_modules/npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/cliui/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/@isaacs/string-locale-compare": {
+ "version": "1.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/@npmcli/agent": {
+ "version": "2.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "http-proxy-agent": "^7.0.0",
+ "https-proxy-agent": "^7.0.1",
+ "lru-cache": "^10.0.1",
+ "socks-proxy-agent": "^8.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/arborist": {
+ "version": "7.3.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@isaacs/string-locale-compare": "^1.1.0",
+ "@npmcli/fs": "^3.1.0",
+ "@npmcli/installed-package-contents": "^2.0.2",
+ "@npmcli/map-workspaces": "^3.0.2",
+ "@npmcli/metavuln-calculator": "^7.0.0",
+ "@npmcli/name-from-folder": "^2.0.0",
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/query": "^3.0.1",
+ "@npmcli/run-script": "^7.0.2",
+ "bin-links": "^4.0.1",
+ "cacache": "^18.0.0",
+ "common-ancestor-path": "^1.0.1",
+ "hosted-git-info": "^7.0.1",
+ "json-parse-even-better-errors": "^3.0.0",
+ "json-stringify-nice": "^1.1.4",
+ "minimatch": "^9.0.0",
+ "nopt": "^7.0.0",
+ "npm-install-checks": "^6.2.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^16.0.0",
+ "npmlog": "^7.0.1",
+ "pacote": "^17.0.4",
+ "parse-conflict-json": "^3.0.0",
+ "proc-log": "^3.0.0",
+ "promise-all-reject-late": "^1.0.0",
+ "promise-call-limit": "^3.0.1",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "ssri": "^10.0.5",
+ "treeverse": "^3.0.0",
+ "walk-up-path": "^3.0.1"
+ },
+ "bin": {
+ "arborist": "bin/index.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/config": {
+ "version": "8.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/map-workspaces": "^3.0.2",
+ "ci-info": "^4.0.0",
+ "ini": "^4.1.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.5",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/disparity-colors": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ansi-styles": "^4.3.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/disparity-colors/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/fs": {
+ "version": "3.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/git": {
+ "version": "5.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/promise-spawn": "^7.0.0",
+ "lru-cache": "^10.0.1",
+ "npm-pick-manifest": "^9.0.0",
+ "proc-log": "^3.0.0",
+ "promise-inflight": "^1.0.1",
+ "promise-retry": "^2.0.1",
+ "semver": "^7.3.5",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/installed-package-contents": {
+ "version": "2.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-bundled": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "bin": {
+ "installed-package-contents": "lib/index.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/map-workspaces": {
+ "version": "3.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/name-from-folder": "^2.0.0",
+ "glob": "^10.2.2",
+ "minimatch": "^9.0.0",
+ "read-package-json-fast": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/metavuln-calculator": {
+ "version": "7.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cacache": "^18.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "pacote": "^17.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/name-from-folder": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/node-gyp": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/package-json": {
+ "version": "5.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "glob": "^10.2.2",
+ "hosted-git-info": "^7.0.0",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/promise-spawn": {
+ "version": "7.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/query": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "postcss-selector-parser": "^6.0.10"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@npmcli/run-script": {
+ "version": "7.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/node-gyp": "^3.0.0",
+ "@npmcli/package-json": "^5.0.0",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "node-gyp": "^10.0.0",
+ "which": "^4.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/bundle": {
+ "version": "2.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/core": {
+ "version": "0.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/protobuf-specs": {
+ "version": "0.2.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/sign": {
+ "version": "2.2.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.1.1",
+ "@sigstore/core": "^0.2.0",
+ "@sigstore/protobuf-specs": "^0.2.1",
+ "make-fetch-happen": "^13.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/tuf": {
+ "version": "2.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/protobuf-specs": "^0.2.1",
+ "tuf-js": "^2.2.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@sigstore/verify": {
+ "version": "0.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.1.1",
+ "@sigstore/core": "^0.2.0",
+ "@sigstore/protobuf-specs": "^0.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@tufjs/canonical-json": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/@tufjs/models": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tufjs/canonical-json": "2.0.0",
+ "minimatch": "^9.0.3"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/abbrev": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/agent-base": {
+ "version": "7.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/aggregate-error": {
+ "version": "3.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ansi-styles": {
+ "version": "6.2.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/aproba": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/archy": {
+ "version": "1.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/are-we-there-yet": {
+ "version": "4.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/balanced-match": {
+ "version": "1.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/bin-links": {
+ "version": "4.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cmd-shim": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "read-cmd-shim": "^4.0.0",
+ "write-file-atomic": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/binary-extensions": {
+ "version": "2.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/builtins": {
+ "version": "5.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/cacache": {
+ "version": "18.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/fs": "^3.1.0",
+ "fs-minipass": "^3.0.0",
+ "glob": "^10.2.2",
+ "lru-cache": "^10.0.1",
+ "minipass": "^7.0.3",
+ "minipass-collect": "^2.0.1",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "p-map": "^4.0.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11",
+ "unique-filename": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/chalk": {
+ "version": "5.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/chownr": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ci-info": {
+ "version": "4.0.0",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/sibiraj-s"
+ }
+ ],
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/cidr-regex": {
+ "version": "4.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "ip-regex": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/clean-stack": {
+ "version": "2.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/cli-columns": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">= 10"
+ }
+ },
+ "node_modules/npm/node_modules/cli-table3": {
+ "version": "0.6.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/npm/node_modules/clone": {
+ "version": "1.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/npm/node_modules/cmd-shim": {
+ "version": "6.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-convert": {
+ "version": "2.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/color-name": {
+ "version": "1.1.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/color-support": {
+ "version": "1.1.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "bin": {
+ "color-support": "bin.js"
+ }
+ },
+ "node_modules/npm/node_modules/columnify": {
+ "version": "1.6.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "strip-ansi": "^6.0.1",
+ "wcwidth": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/common-ancestor-path": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/console-control-strings": {
+ "version": "1.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/cross-spawn": {
+ "version": "7.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cross-spawn/node_modules/which": {
+ "version": "2.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/cssesc": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "cssesc": "bin/cssesc"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/debug": {
+ "version": "4.3.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/npm/node_modules/debug/node_modules/ms": {
+ "version": "2.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/defaults": {
+ "version": "1.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "clone": "^1.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/diff": {
+ "version": "5.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/npm/node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/encoding": {
+ "version": "0.1.13",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
+ "node_modules/npm/node_modules/env-paths": {
+ "version": "2.2.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/npm/node_modules/err-code": {
+ "version": "2.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/exponential-backoff": {
+ "version": "3.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0"
+ },
+ "node_modules/npm/node_modules/fastest-levenshtein": {
+ "version": "1.0.16",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4.9.1"
+ }
+ },
+ "node_modules/npm/node_modules/foreground-child": {
+ "version": "3.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.0",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/fs-minipass": {
+ "version": "3.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/function-bind": {
+ "version": "1.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/gauge": {
+ "version": "5.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^1.0.3 || ^2.0.0",
+ "color-support": "^1.1.3",
+ "console-control-strings": "^1.1.0",
+ "has-unicode": "^2.0.1",
+ "signal-exit": "^4.0.1",
+ "string-width": "^4.2.3",
+ "strip-ansi": "^6.0.1",
+ "wide-align": "^1.1.5"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/glob": {
+ "version": "10.3.10",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^2.3.5",
+ "minimatch": "^9.0.1",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0",
+ "path-scurry": "^1.10.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/graceful-fs": {
+ "version": "4.2.11",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/has-unicode": {
+ "version": "2.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/hasown": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/npm/node_modules/hosted-git-info": {
+ "version": "7.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^10.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/http-cache-semantics": {
+ "version": "4.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/npm/node_modules/http-proxy-agent": {
+ "version": "7.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.0",
+ "debug": "^4.3.4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/https-proxy-agent": {
+ "version": "7.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/npm/node_modules/ignore-walk": {
+ "version": "6.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minimatch": "^9.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/npm/node_modules/indent-string": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/ini": {
+ "version": "4.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/init-package-json": {
+ "version": "6.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-package-arg": "^11.0.0",
+ "promzard": "^1.0.0",
+ "read": "^2.0.0",
+ "read-package-json": "^7.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/ip": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/ip-regex": {
+ "version": "5.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/is-cidr": {
+ "version": "5.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "cidr-regex": "4.0.3"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/npm/node_modules/is-core-module": {
+ "version": "2.13.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "hasown": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/npm/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/is-lambda": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/isexe": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/jackspeak": {
+ "version": "2.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/npm/node_modules/json-parse-even-better-errors": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/json-stringify-nice": {
+ "version": "1.1.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/jsonparse": {
+ "version": "1.3.1",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff": {
+ "version": "6.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/just-diff-apply": {
+ "version": "5.5.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/libnpmaccess": {
+ "version": "8.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-package-arg": "^11.0.1",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmdiff": {
+ "version": "6.0.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/disparity-colors": "^3.0.0",
+ "@npmcli/installed-package-contents": "^2.0.2",
+ "binary-extensions": "^2.2.0",
+ "diff": "^5.1.0",
+ "minimatch": "^9.0.0",
+ "npm-package-arg": "^11.0.1",
+ "pacote": "^17.0.4",
+ "tar": "^6.2.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmexec": {
+ "version": "7.0.7",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/run-script": "^7.0.2",
+ "ci-info": "^4.0.0",
+ "npm-package-arg": "^11.0.1",
+ "npmlog": "^7.0.1",
+ "pacote": "^17.0.4",
+ "proc-log": "^3.0.0",
+ "read": "^2.0.0",
+ "read-package-json-fast": "^3.0.2",
+ "semver": "^7.3.7",
+ "walk-up-path": "^3.0.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmfund": {
+ "version": "5.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmhook": {
+ "version": "10.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmorg": {
+ "version": "6.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpack": {
+ "version": "6.0.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/arborist": "^7.2.1",
+ "@npmcli/run-script": "^7.0.2",
+ "npm-package-arg": "^11.0.1",
+ "pacote": "^17.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmpublish": {
+ "version": "9.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ci-info": "^4.0.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-package-arg": "^11.0.1",
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.7",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmsearch": {
+ "version": "7.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmteam": {
+ "version": "6.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "aproba": "^2.0.0",
+ "npm-registry-fetch": "^16.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/libnpmversion": {
+ "version": "5.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.3",
+ "@npmcli/run-script": "^7.0.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/lru-cache": {
+ "version": "10.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "14 || >=16.14"
+ }
+ },
+ "node_modules/npm/node_modules/make-fetch-happen": {
+ "version": "13.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/agent": "^2.0.0",
+ "cacache": "^18.0.0",
+ "http-cache-semantics": "^4.1.1",
+ "is-lambda": "^1.0.1",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-flush": "^1.0.5",
+ "minipass-pipeline": "^1.2.4",
+ "negotiator": "^0.6.3",
+ "promise-retry": "^2.0.1",
+ "ssri": "^10.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minimatch": {
+ "version": "9.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/minipass": {
+ "version": "7.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-collect": {
+ "version": "2.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-fetch": {
+ "version": "3.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^7.0.3",
+ "minipass-sized": "^1.0.3",
+ "minizlib": "^2.1.2"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ },
+ "optionalDependencies": {
+ "encoding": "^0.1.13"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-flush": {
+ "version": "1.0.5",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-flush/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "jsonparse": "^1.3.1",
+ "minipass": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-json-stream/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline": {
+ "version": "1.2.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-pipeline/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized": {
+ "version": "1.0.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minipass-sized/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib": {
+ "version": "2.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "minipass": "^3.0.0",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/minizlib/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/mkdirp": {
+ "version": "1.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "bin": {
+ "mkdirp": "bin/cmd.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/ms": {
+ "version": "2.1.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/mute-stream": {
+ "version": "1.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/negotiator": {
+ "version": "0.6.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/npm/node_modules/node-gyp": {
+ "version": "10.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.0",
+ "exponential-backoff": "^3.1.1",
+ "glob": "^10.3.10",
+ "graceful-fs": "^4.2.6",
+ "make-fetch-happen": "^13.0.0",
+ "nopt": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "tar": "^6.1.2",
+ "which": "^4.0.0"
+ },
+ "bin": {
+ "node-gyp": "bin/node-gyp.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/nopt": {
+ "version": "7.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "abbrev": "^2.0.0"
+ },
+ "bin": {
+ "nopt": "bin/nopt.js"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/normalize-package-data": {
+ "version": "6.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "is-core-module": "^2.8.1",
+ "semver": "^7.3.5",
+ "validate-npm-package-license": "^3.0.4"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-audit-report": {
+ "version": "5.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-bundled": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-install-checks": {
+ "version": "6.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "semver": "^7.1.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-normalize-package-bin": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-package-arg": {
+ "version": "11.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "hosted-git-info": "^7.0.0",
+ "proc-log": "^3.0.0",
+ "semver": "^7.3.5",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-packlist": {
+ "version": "8.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "ignore-walk": "^6.0.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-pick-manifest": {
+ "version": "9.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-install-checks": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0",
+ "npm-package-arg": "^11.0.0",
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-profile": {
+ "version": "9.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-registry-fetch": {
+ "version": "16.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "make-fetch-happen": "^13.0.0",
+ "minipass": "^7.0.2",
+ "minipass-fetch": "^3.0.0",
+ "minipass-json-stream": "^1.0.1",
+ "minizlib": "^2.1.2",
+ "npm-package-arg": "^11.0.0",
+ "proc-log": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npm-user-validate": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/npmlog": {
+ "version": "7.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "are-we-there-yet": "^4.0.0",
+ "console-control-strings": "^1.1.0",
+ "gauge": "^5.0.0",
+ "set-blocking": "^2.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/p-map": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "aggregate-error": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/pacote": {
+ "version": "17.0.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "@npmcli/git": "^5.0.0",
+ "@npmcli/installed-package-contents": "^2.0.1",
+ "@npmcli/promise-spawn": "^7.0.0",
+ "@npmcli/run-script": "^7.0.0",
+ "cacache": "^18.0.0",
+ "fs-minipass": "^3.0.0",
+ "minipass": "^7.0.2",
+ "npm-package-arg": "^11.0.0",
+ "npm-packlist": "^8.0.0",
+ "npm-pick-manifest": "^9.0.0",
+ "npm-registry-fetch": "^16.0.0",
+ "proc-log": "^3.0.0",
+ "promise-retry": "^2.0.1",
+ "read-package-json": "^7.0.0",
+ "read-package-json-fast": "^3.0.0",
+ "sigstore": "^2.2.0",
+ "ssri": "^10.0.0",
+ "tar": "^6.1.11"
+ },
+ "bin": {
+ "pacote": "lib/bin.js"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/parse-conflict-json": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "just-diff": "^6.0.0",
+ "just-diff-apply": "^5.2.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/path-key": {
+ "version": "3.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/path-scurry": {
+ "version": "1.10.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^9.1.1 || ^10.0.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/postcss-selector-parser": {
+ "version": "6.0.15",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "cssesc": "^3.0.0",
+ "util-deprecate": "^1.0.2"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/npm/node_modules/proc-log": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/promise-all-reject-late": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-call-limit": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/promise-inflight": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/promise-retry": {
+ "version": "2.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "err-code": "^2.0.2",
+ "retry": "^0.12.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/promzard": {
+ "version": "1.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "read": "^2.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/qrcode-terminal": {
+ "version": "0.12.0",
+ "dev": true,
+ "inBundle": true,
+ "bin": {
+ "qrcode-terminal": "bin/qrcode-terminal.js"
+ }
+ },
+ "node_modules/npm/node_modules/read": {
+ "version": "2.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "mute-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-cmd-shim": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-package-json": {
+ "version": "7.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "glob": "^10.2.2",
+ "json-parse-even-better-errors": "^3.0.0",
+ "normalize-package-data": "^6.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/read-package-json-fast": {
+ "version": "3.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "json-parse-even-better-errors": "^3.0.0",
+ "npm-normalize-package-bin": "^3.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/retry": {
+ "version": "0.12.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/npm/node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true
+ },
+ "node_modules/npm/node_modules/semver": {
+ "version": "7.5.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/set-blocking": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/shebang-command": {
+ "version": "2.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/npm/node_modules/sigstore": {
+ "version": "2.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@sigstore/bundle": "^2.1.1",
+ "@sigstore/core": "^0.2.0",
+ "@sigstore/protobuf-specs": "^0.2.1",
+ "@sigstore/sign": "^2.2.1",
+ "@sigstore/tuf": "^2.3.0",
+ "@sigstore/verify": "^0.1.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/smart-buffer": {
+ "version": "4.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 6.0.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks": {
+ "version": "2.7.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ip": "^2.0.0",
+ "smart-buffer": "^4.2.0"
+ },
+ "engines": {
+ "node": ">= 10.13.0",
+ "npm": ">= 3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/socks-proxy-agent": {
+ "version": "8.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.0.2",
+ "debug": "^4.3.4",
+ "socks": "^2.7.1"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-exceptions": {
+ "version": "2.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "CC-BY-3.0"
+ },
+ "node_modules/npm/node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/spdx-license-ids": {
+ "version": "3.0.16",
+ "dev": true,
+ "inBundle": true,
+ "license": "CC0-1.0"
+ },
+ "node_modules/npm/node_modules/ssri": {
+ "version": "10.0.5",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^7.0.3"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/string-width": {
+ "version": "4.2.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/supports-color": {
+ "version": "9.4.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-color?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/tar": {
+ "version": "6.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "chownr": "^2.0.0",
+ "fs-minipass": "^2.0.0",
+ "minipass": "^5.0.0",
+ "minizlib": "^2.1.1",
+ "mkdirp": "^1.0.3",
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass": {
+ "version": "2.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "minipass": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/fs-minipass/node_modules/minipass": {
+ "version": "3.3.6",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/tar/node_modules/minipass": {
+ "version": "5.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/npm/node_modules/text-table": {
+ "version": "0.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/tiny-relative-date": {
+ "version": "1.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/treeverse": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/tuf-js": {
+ "version": "2.2.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "@tufjs/models": "2.0.0",
+ "debug": "^4.3.4",
+ "make-fetch-happen": "^13.0.0"
+ },
+ "engines": {
+ "node": "^16.14.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/unique-filename": {
+ "version": "3.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "unique-slug": "^4.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/unique-slug": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/validate-npm-package-name": {
+ "version": "5.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "builtins": "^5.0.0"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/walk-up-path": {
+ "version": "3.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/npm/node_modules/wcwidth": {
+ "version": "1.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "defaults": "^1.0.3"
+ }
+ },
+ "node_modules/npm/node_modules/which": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^3.1.1"
+ },
+ "bin": {
+ "node-which": "bin/which.js"
+ },
+ "engines": {
+ "node": "^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/which/node_modules/isexe": {
+ "version": "3.1.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/npm/node_modules/wide-align": {
+ "version": "1.1.5",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^1.0.2 || 2 || 3 || 4"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/ansi-regex": {
+ "version": "6.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT"
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "5.1.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/npm/node_modules/wrap-ansi/node_modules/strip-ansi": {
+ "version": "7.1.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/npm/node_modules/write-file-atomic": {
+ "version": "5.0.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC",
+ "dependencies": {
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/npm/node_modules/yallist": {
+ "version": "4.0.0",
+ "dev": true,
+ "inBundle": true,
+ "license": "ISC"
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "dev": true,
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-each-series": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-3.0.0.tgz",
+ "integrity": "sha512-lastgtAdoH9YaLyDa5i5z64q+kzOcQHsQ5SsZJD3q0VEyI8mq872S3geuNbRUQLVAE9siMfgKrpj7MloKFHruw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-filter": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-4.1.0.tgz",
+ "integrity": "sha512-37/tPdZ3oJwHaS3gNJdenCDB3Tz26i9sjhnguBtvN0vYlRIiDNnvTWkuh+0hETV9rLPdJ3rlL3yVOYPIAnM8rw==",
+ "dev": true,
+ "dependencies": {
+ "p-map": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-is-promise": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-3.0.0.tgz",
+ "integrity": "sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/p-map": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.1.tgz",
+ "integrity": "sha512-2wnaR0XL/FDOj+TgpDuRb2KTjLnu3Fma6b1ZUwGY7LcqenMcvP/YFpjpbPKY6WVGsbuJZRuoUz8iPrt8ORnAFw==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-reduce": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz",
+ "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parsimmon": {
+ "version": "1.18.1",
+ "resolved": "https://registry.npmjs.org/parsimmon/-/parsimmon-1.18.1.tgz",
+ "integrity": "sha512-u7p959wLfGAhJpSDJVYXoyMCXWYwHia78HhRBWqk7AIbxdmlrfdp5wX0l3xv/iTSH5HvhN9K7o26hwwpgS5Nmw==",
+ "dev": true
+ },
+ "node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-type": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
+ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+ "dev": true,
+ "engines": {
+ "node": ">=8.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/pkg-conf": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha512-C+VUP+8jis7EsQZIhDYmS5qlNtjv2yP4SNtjXK9AP1ZcTRlnSfuumaTnRfYZnYgUUYVIKqL0fRvmUGDV2fmp6g==",
+ "dev": true,
+ "dependencies": {
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/process-nextick-args": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
+ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
+ "dev": true
+ },
+ "node_modules/promisified-properties": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/promisified-properties/-/promisified-properties-3.0.0.tgz",
+ "integrity": "sha512-ARteuBuUpPg/+spsMhcKHvdtOW/q8btyyVYYxxegGgx+7u9ix9at8DjP2KM2t8+4SuI8wBLt+3X876FMQx91yQ==",
+ "dev": true,
+ "dependencies": {
+ "parsimmon": "^1.13.0"
+ },
+ "engines": {
+ "node": ">=18",
+ "npm": ">=7.12"
+ }
+ },
+ "node_modules/proto-list": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
+ "dev": true
+ },
+ "node_modules/queue-microtask": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
+ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ]
+ },
+ "node_modules/rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "dependencies": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "bin": {
+ "rc": "cli.js"
+ }
+ },
+ "node_modules/read-pkg": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-9.0.1.tgz",
+ "integrity": "sha512-9viLL4/n1BJUCT1NXVTdS1jtm80yDEgR5T4yCelII49Mbj0v1rZdKqj7zCiYdbB0CuCgdrvHcNogAKTFPBocFA==",
+ "dev": true,
+ "dependencies": {
+ "@types/normalize-package-data": "^2.4.3",
+ "normalize-package-data": "^6.0.0",
+ "parse-json": "^8.0.0",
+ "type-fest": "^4.6.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg-up": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-11.0.0.tgz",
+ "integrity": "sha512-LOVbvF1Q0SZdjClSefZ0Nz5z8u+tIE7mV5NibzmE9VYmDe9CaBbAVtz1veOSZbofrdsilxuDAYnFenukZVp8/Q==",
+ "deprecated": "Renamed to read-package-up",
+ "dev": true,
+ "dependencies": {
+ "find-up-simple": "^1.0.0",
+ "read-pkg": "^9.0.0",
+ "type-fest": "^4.6.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg-up/node_modules/type-fest": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz",
+ "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg/node_modules/parse-json": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-8.1.0.tgz",
+ "integrity": "sha512-rum1bPifK5SSar35Z6EKZuYPJx85pkNaFrxBK3mwdfSJ1/WKbYrjoW/zTPSjRRamfmVX1ACBIdFAO0VRErW/EA==",
+ "dev": true,
+ "dependencies": {
+ "@babel/code-frame": "^7.22.13",
+ "index-to-position": "^0.1.2",
+ "type-fest": "^4.7.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/read-pkg/node_modules/type-fest": {
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.10.1.tgz",
+ "integrity": "sha512-7ZnJYTp6uc04uYRISWtiX3DSKB/fxNQT0B5o1OUeCqiQiwF+JC9+rJiZIDrPrNCLLuTqyQmh4VdQqh/ZOkv9MQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/readable-stream": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
+ "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
+ "dev": true,
+ "dependencies": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "node_modules/redeyed": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-2.1.1.tgz",
+ "integrity": "sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==",
+ "dev": true,
+ "dependencies": {
+ "esprima": "~4.0.0"
+ }
+ },
+ "node_modules/registry-auth-token": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-5.0.2.tgz",
+ "integrity": "sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==",
+ "dev": true,
+ "dependencies": {
+ "@pnpm/npm-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true,
+ "engines": {
+ "iojs": ">=1.0.0",
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/run-parallel": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
+ "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/feross"
+ },
+ {
+ "type": "patreon",
+ "url": "https://www.patreon.com/feross"
+ },
+ {
+ "type": "consulting",
+ "url": "https://feross.org/support"
+ }
+ ],
+ "dependencies": {
+ "queue-microtask": "^1.2.2"
+ }
+ },
+ "node_modules/safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+ "dev": true
+ },
+ "node_modules/semantic-release": {
+ "version": "23.0.0",
+ "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.0.0.tgz",
+ "integrity": "sha512-Jz7jEWO2igTtske112gC4PPE2whCMVrsgxUPG3/SZI7VE357suIUZFlJd1Yu0g2I6RPc2HxNEfUg7KhmDTjwqg==",
+ "dev": true,
+ "dependencies": {
+ "@semantic-release/commit-analyzer": "^11.0.0",
+ "@semantic-release/error": "^4.0.0",
+ "@semantic-release/github": "^9.0.0",
+ "@semantic-release/npm": "^11.0.0",
+ "@semantic-release/release-notes-generator": "^12.0.0",
+ "aggregate-error": "^5.0.0",
+ "cosmiconfig": "^9.0.0",
+ "debug": "^4.0.0",
+ "env-ci": "^11.0.0",
+ "execa": "^8.0.0",
+ "figures": "^6.0.0",
+ "find-versions": "^5.1.0",
+ "get-stream": "^6.0.0",
+ "git-log-parser": "^1.2.0",
+ "hook-std": "^3.0.0",
+ "hosted-git-info": "^7.0.0",
+ "import-from-esm": "^1.3.1",
+ "lodash-es": "^4.17.21",
+ "marked": "^11.0.0",
+ "marked-terminal": "^6.0.0",
+ "micromatch": "^4.0.2",
+ "p-each-series": "^3.0.0",
+ "p-reduce": "^3.0.0",
+ "read-pkg-up": "^11.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^7.3.2",
+ "semver-diff": "^4.0.0",
+ "signale": "^1.2.1",
+ "yargs": "^17.5.1"
+ },
+ "bin": {
+ "semantic-release": "bin/semantic-release.js"
+ },
+ "engines": {
+ "node": ">=20.8.1"
+ }
+ },
+ "node_modules/semantic-release/node_modules/@semantic-release/error": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@semantic-release/error/-/error-4.0.0.tgz",
+ "integrity": "sha512-mgdxrHTLOjOddRVYIYDo0fR3/v61GNN1YGkfbrjuIKg/uMgCd+Qzo3UAXJ+woLQQpos4pl5Esuw5A7AoNlzjUQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/semantic-release/node_modules/aggregate-error": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz",
+ "integrity": "sha512-gOsf2YwSlleG6IjRYG2A7k0HmBMEo6qVNk9Bp/EaLgAJT5ngH6PXbqa4ItvnEwCm/velL5jAnQgsHsWnjhGmvw==",
+ "dev": true,
+ "dependencies": {
+ "clean-stack": "^5.2.0",
+ "indent-string": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/clean-stack": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-5.2.0.tgz",
+ "integrity": "sha512-TyUIUJgdFnCISzG5zu3291TAsE77ddchd0bepon1VVQrKLGKFED4iXFEDQ24mIPdPBbyE16PK3F8MYE1CmcBEQ==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "5.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/escape-string-regexp": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz",
+ "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/execa": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz",
+ "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==",
+ "dev": true,
+ "dependencies": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^8.0.1",
+ "human-signals": "^5.0.0",
+ "is-stream": "^3.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^5.1.0",
+ "onetime": "^6.0.0",
+ "signal-exit": "^4.1.0",
+ "strip-final-newline": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=16.17"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
+ }
+ },
+ "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz",
+ "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==",
+ "dev": true,
+ "engines": {
+ "node": ">=16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/human-signals": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz",
+ "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.17.0"
+ }
+ },
+ "node_modules/semantic-release/node_modules/indent-string": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-5.0.0.tgz",
+ "integrity": "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/mimic-fn": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
+ "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/npm-run-path": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz",
+ "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==",
+ "dev": true,
+ "dependencies": {
+ "path-key": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/onetime": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
+ "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
+ "dev": true,
+ "dependencies": {
+ "mimic-fn": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/p-reduce": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz",
+ "integrity": "sha512-xsrIUgI0Kn6iyDYm9StOpOeK29XM1aboGji26+QEortiFST1hGZaUQOLhtEbqHErPpGW/aSz6allwK2qcptp0Q==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/path-key": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semantic-release/node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/semantic-release/node_modules/strip-final-newline": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
+ "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
+ "dev": true,
+ "dependencies": {
+ "lru-cache": "^6.0.0"
+ },
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/semver-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-4.0.0.tgz",
+ "integrity": "sha512-0Ju4+6A8iOnpL/Thra7dZsSlOHYAHIeMxfhWQRI1/VLcT3WDBZKKtQt/QkBOsiIN9ZpuvHE6cGZ0x4glCMmfiA==",
+ "dev": true,
+ "dependencies": {
+ "semver": "^7.3.5"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semver-regex": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz",
+ "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/semver/node_modules/lru-cache": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+ "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+ "dev": true,
+ "dependencies": {
+ "yallist": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "dev": true
+ },
+ "node_modules/signale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/signale/-/signale-1.4.0.tgz",
+ "integrity": "sha512-iuh+gPf28RkltuJC7W5MRi6XAjTDCAPC/prJUpQoG4vIP3MJZ+GTydVnodXA7pwvTKb2cA0m9OFZW/cdWy/I/w==",
+ "dev": true,
+ "dependencies": {
+ "chalk": "^2.3.2",
+ "figures": "^2.0.0",
+ "pkg-conf": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/signale/node_modules/ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "dependencies": {
+ "color-convert": "^1.9.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "dependencies": {
+ "color-name": "1.1.3"
+ }
+ },
+ "node_modules/signale/node_modules/color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==",
+ "dev": true
+ },
+ "node_modules/signale/node_modules/figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==",
+ "dev": true,
+ "dependencies": {
+ "escape-string-regexp": "^1.0.5"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/signale/node_modules/supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/skin-tone": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz",
+ "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==",
+ "dev": true,
+ "dependencies": {
+ "unicode-emoji-modifier-base": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slash": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
+ "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/source-map": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/spawn-error-forwarder": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz",
+ "integrity": "sha512-gRjMgK5uFjbCvdibeGJuy3I5OYz6VLoVdsOJdA6wV0WlfQVLFueoqMxwwYD9RODdgb6oUIvlRlsyFSiQkMKu0g==",
+ "dev": true
+ },
+ "node_modules/spdx-correct": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz",
+ "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==",
+ "dev": true,
+ "dependencies": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-exceptions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.4.0.tgz",
+ "integrity": "sha512-hcjppoJ68fhxA/cjbN4T8N6uCUejN8yFw69ttpqtBeCbF3u13n7mb31NB9jKwGTTWWnt9IbRA/mf1FprYS8wfw==",
+ "dev": true
+ },
+ "node_modules/spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "dev": true,
+ "dependencies": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "node_modules/spdx-license-ids": {
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz",
+ "integrity": "sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw==",
+ "dev": true
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stream-combiner2": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz",
+ "integrity": "sha512-3PnJbYgS56AeWgtKF5jtJRT6uFJe56Z0Hc5Ngg/6sI6rIt8iiMBTa9cvdyFfpMQjaVHr8dusbNeFGIIonxOvKw==",
+ "dev": true,
+ "dependencies": {
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "node_modules/string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "dependencies": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
+ "dev": true,
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz",
+ "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==",
+ "dev": true,
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=14.18"
+ }
+ },
+ "node_modules/temp-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-3.0.0.tgz",
+ "integrity": "sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ }
+ },
+ "node_modules/tempy": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/tempy/-/tempy-3.1.0.tgz",
+ "integrity": "sha512-7jDLIdD2Zp0bDe5r3D2qtkd1QOCacylBuL7oa4udvN6v2pqr4+LcCr67C8DR1zkpaZ8XosF5m1yQSabKAW6f2g==",
+ "dev": true,
+ "dependencies": {
+ "is-stream": "^3.0.0",
+ "temp-dir": "^3.0.0",
+ "type-fest": "^2.12.2",
+ "unique-string": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/is-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
+ "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/tempy/node_modules/type-fest": {
+ "version": "2.19.0",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz",
+ "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==",
+ "dev": true,
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true,
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true
+ },
+ "node_modules/through2": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+ "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+ "dev": true,
+ "dependencies": {
+ "readable-stream": "~2.3.6",
+ "xtend": "~4.0.1"
+ }
+ },
+ "node_modules/to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "dependencies": {
+ "is-number": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=8.0"
+ }
+ },
+ "node_modules/traverse": {
+ "version": "0.6.8",
+ "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.8.tgz",
+ "integrity": "sha512-aXJDbk6SnumuaZSANd21XAo15ucCDE38H4fkqiGsc3MhCK+wOlZvLP9cB/TvpHT0mOyWgC4Z8EwRlzqYSUzdsA==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/type-fest": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-3.13.1.tgz",
+ "integrity": "sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==",
+ "dev": true,
+ "engines": {
+ "node": ">=14.16"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/uglify-js": {
+ "version": "3.17.4",
+ "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz",
+ "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==",
+ "dev": true,
+ "optional": true,
+ "bin": {
+ "uglifyjs": "bin/uglifyjs"
+ },
+ "engines": {
+ "node": ">=0.8.0"
+ }
+ },
+ "node_modules/unicode-emoji-modifier-base": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz",
+ "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/unique-string": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-3.0.0.tgz",
+ "integrity": "sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==",
+ "dev": true,
+ "dependencies": {
+ "crypto-random-string": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/universal-user-agent": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz",
+ "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==",
+ "dev": true
+ },
+ "node_modules/universalify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
+ "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10.0.0"
+ }
+ },
+ "node_modules/url-join": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz",
+ "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==",
+ "dev": true,
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
+ "dev": true
+ },
+ "node_modules/validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "dev": true,
+ "dependencies": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==",
+ "dev": true
+ },
+ "node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "dev": true
+ },
+ "node_modules/xtend": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
+ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=0.4"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yallist": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+ "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+ "dev": true
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "engines": {
+ "node": ">=12"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..d179657a
--- /dev/null
+++ b/package.json
@@ -0,0 +1,10 @@
+{
+ "devDependencies": {
+ "@codedependant/semantic-release-docker": "^5.0.3",
+ "@saithodev/semantic-release-backmerge": "^4.0.1",
+ "@semantic-release/changelog": "^6.0.3",
+ "@semantic-release/git": "^10.0.1",
+ "gradle-semantic-release-plugin": "^1.9.2",
+ "semantic-release": "^24.0.0"
+ }
+}
\ No newline at end of file
diff --git a/persistence/.gitkeep b/persistence/.gitkeep
deleted file mode 100644
index e69de29b..00000000
diff --git a/poetry.lock b/poetry.lock
deleted file mode 100644
index ff84b977..00000000
--- a/poetry.lock
+++ /dev/null
@@ -1,2426 +0,0 @@
-# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand.
-
-[[package]]
-name = "aiodns"
-version = "3.1.1"
-description = "Simple DNS resolver for asyncio"
-optional = false
-python-versions = "*"
-files = [
- {file = "aiodns-3.1.1-py3-none-any.whl", hash = "sha256:a387b63da4ced6aad35b1dda2d09620ad608a1c7c0fb71efa07ebb4cd511928d"},
- {file = "aiodns-3.1.1.tar.gz", hash = "sha256:1073eac48185f7a4150cad7f96a5192d6911f12b4fb894de80a088508c9b3a99"},
-]
-
-[package.dependencies]
-pycares = ">=4.0.0"
-
-[[package]]
-name = "aiofiles"
-version = "23.2.1"
-description = "File support for asyncio."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "aiofiles-23.2.1-py3-none-any.whl", hash = "sha256:19297512c647d4b27a2cf7c34caa7e405c0d60b5560618a29a9fe027b18b0107"},
- {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"},
-]
-
-[[package]]
-name = "aiohttp"
-version = "3.9.1"
-description = "Async http client/server framework (asyncio)"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1f80197f8b0b846a8d5cf7b7ec6084493950d0882cc5537fb7b96a69e3c8590"},
- {file = "aiohttp-3.9.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c72444d17777865734aa1a4d167794c34b63e5883abb90356a0364a28904e6c0"},
- {file = "aiohttp-3.9.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9b05d5cbe9dafcdc733262c3a99ccf63d2f7ce02543620d2bd8db4d4f7a22f83"},
- {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c4fa235d534b3547184831c624c0b7c1e262cd1de847d95085ec94c16fddcd5"},
- {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:289ba9ae8e88d0ba16062ecf02dd730b34186ea3b1e7489046fc338bdc3361c4"},
- {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bff7e2811814fa2271be95ab6e84c9436d027a0e59665de60edf44e529a42c1f"},
- {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81b77f868814346662c96ab36b875d7814ebf82340d3284a31681085c051320f"},
- {file = "aiohttp-3.9.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b9c7426923bb7bd66d409da46c41e3fb40f5caf679da624439b9eba92043fa6"},
- {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8d44e7bf06b0c0a70a20f9100af9fcfd7f6d9d3913e37754c12d424179b4e48f"},
- {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:22698f01ff5653fe66d16ffb7658f582a0ac084d7da1323e39fd9eab326a1f26"},
- {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ca7ca5abfbfe8d39e653870fbe8d7710be7a857f8a8386fc9de1aae2e02ce7e4"},
- {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:8d7f98fde213f74561be1d6d3fa353656197f75d4edfbb3d94c9eb9b0fc47f5d"},
- {file = "aiohttp-3.9.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5216b6082c624b55cfe79af5d538e499cd5f5b976820eac31951fb4325974501"},
- {file = "aiohttp-3.9.1-cp310-cp310-win32.whl", hash = "sha256:0e7ba7ff228c0d9a2cd66194e90f2bca6e0abca810b786901a569c0de082f489"},
- {file = "aiohttp-3.9.1-cp310-cp310-win_amd64.whl", hash = "sha256:c7e939f1ae428a86e4abbb9a7c4732bf4706048818dfd979e5e2839ce0159f23"},
- {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:df9cf74b9bc03d586fc53ba470828d7b77ce51b0582d1d0b5b2fb673c0baa32d"},
- {file = "aiohttp-3.9.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ecca113f19d5e74048c001934045a2b9368d77b0b17691d905af18bd1c21275e"},
- {file = "aiohttp-3.9.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8cef8710fb849d97c533f259103f09bac167a008d7131d7b2b0e3a33269185c0"},
- {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bea94403a21eb94c93386d559bce297381609153e418a3ffc7d6bf772f59cc35"},
- {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91c742ca59045dce7ba76cab6e223e41d2c70d79e82c284a96411f8645e2afff"},
- {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c93b7c2e52061f0925c3382d5cb8980e40f91c989563d3d32ca280069fd6a87"},
- {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee2527134f95e106cc1653e9ac78846f3a2ec1004cf20ef4e02038035a74544d"},
- {file = "aiohttp-3.9.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11ff168d752cb41e8492817e10fb4f85828f6a0142b9726a30c27c35a1835f01"},
- {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b8c3a67eb87394386847d188996920f33b01b32155f0a94f36ca0e0c635bf3e3"},
- {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c7b5d5d64e2a14e35a9240b33b89389e0035e6de8dbb7ffa50d10d8b65c57449"},
- {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:69985d50a2b6f709412d944ffb2e97d0be154ea90600b7a921f95a87d6f108a2"},
- {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c9110c06eaaac7e1f5562caf481f18ccf8f6fdf4c3323feab28a93d34cc646bd"},
- {file = "aiohttp-3.9.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d737e69d193dac7296365a6dcb73bbbf53bb760ab25a3727716bbd42022e8d7a"},
- {file = "aiohttp-3.9.1-cp311-cp311-win32.whl", hash = "sha256:4ee8caa925aebc1e64e98432d78ea8de67b2272252b0a931d2ac3bd876ad5544"},
- {file = "aiohttp-3.9.1-cp311-cp311-win_amd64.whl", hash = "sha256:a34086c5cc285be878622e0a6ab897a986a6e8bf5b67ecb377015f06ed316587"},
- {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f800164276eec54e0af5c99feb9494c295118fc10a11b997bbb1348ba1a52065"},
- {file = "aiohttp-3.9.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:500f1c59906cd142d452074f3811614be04819a38ae2b3239a48b82649c08821"},
- {file = "aiohttp-3.9.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0b0a6a36ed7e164c6df1e18ee47afbd1990ce47cb428739d6c99aaabfaf1b3af"},
- {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69da0f3ed3496808e8cbc5123a866c41c12c15baaaead96d256477edf168eb57"},
- {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:176df045597e674fa950bf5ae536be85699e04cea68fa3a616cf75e413737eb5"},
- {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b796b44111f0cab6bbf66214186e44734b5baab949cb5fb56154142a92989aeb"},
- {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f27fdaadce22f2ef950fc10dcdf8048407c3b42b73779e48a4e76b3c35bca26c"},
- {file = "aiohttp-3.9.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcb6532b9814ea7c5a6a3299747c49de30e84472fa72821b07f5a9818bce0f66"},
- {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:54631fb69a6e44b2ba522f7c22a6fb2667a02fd97d636048478db2fd8c4e98fe"},
- {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4b4c452d0190c5a820d3f5c0f3cd8a28ace48c54053e24da9d6041bf81113183"},
- {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:cae4c0c2ca800c793cae07ef3d40794625471040a87e1ba392039639ad61ab5b"},
- {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:565760d6812b8d78d416c3c7cfdf5362fbe0d0d25b82fed75d0d29e18d7fc30f"},
- {file = "aiohttp-3.9.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:54311eb54f3a0c45efb9ed0d0a8f43d1bc6060d773f6973efd90037a51cd0a3f"},
- {file = "aiohttp-3.9.1-cp312-cp312-win32.whl", hash = "sha256:85c3e3c9cb1d480e0b9a64c658cd66b3cfb8e721636ab8b0e746e2d79a7a9eed"},
- {file = "aiohttp-3.9.1-cp312-cp312-win_amd64.whl", hash = "sha256:11cb254e397a82efb1805d12561e80124928e04e9c4483587ce7390b3866d213"},
- {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8a22a34bc594d9d24621091d1b91511001a7eea91d6652ea495ce06e27381f70"},
- {file = "aiohttp-3.9.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:598db66eaf2e04aa0c8900a63b0101fdc5e6b8a7ddd805c56d86efb54eb66672"},
- {file = "aiohttp-3.9.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2c9376e2b09895c8ca8b95362283365eb5c03bdc8428ade80a864160605715f1"},
- {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41473de252e1797c2d2293804e389a6d6986ef37cbb4a25208de537ae32141dd"},
- {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c5857612c9813796960c00767645cb5da815af16dafb32d70c72a8390bbf690"},
- {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffcd828e37dc219a72c9012ec44ad2e7e3066bec6ff3aaa19e7d435dbf4032ca"},
- {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:219a16763dc0294842188ac8a12262b5671817042b35d45e44fd0a697d8c8361"},
- {file = "aiohttp-3.9.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f694dc8a6a3112059258a725a4ebe9acac5fe62f11c77ac4dcf896edfa78ca28"},
- {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bcc0ea8d5b74a41b621ad4a13d96c36079c81628ccc0b30cfb1603e3dfa3a014"},
- {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:90ec72d231169b4b8d6085be13023ece8fa9b1bb495e4398d847e25218e0f431"},
- {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:cf2a0ac0615842b849f40c4d7f304986a242f1e68286dbf3bd7a835e4f83acfd"},
- {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:0e49b08eafa4f5707ecfb321ab9592717a319e37938e301d462f79b4e860c32a"},
- {file = "aiohttp-3.9.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2c59e0076ea31c08553e868cec02d22191c086f00b44610f8ab7363a11a5d9d8"},
- {file = "aiohttp-3.9.1-cp38-cp38-win32.whl", hash = "sha256:4831df72b053b1eed31eb00a2e1aff6896fb4485301d4ccb208cac264b648db4"},
- {file = "aiohttp-3.9.1-cp38-cp38-win_amd64.whl", hash = "sha256:3135713c5562731ee18f58d3ad1bf41e1d8883eb68b363f2ffde5b2ea4b84cc7"},
- {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:cfeadf42840c1e870dc2042a232a8748e75a36b52d78968cda6736de55582766"},
- {file = "aiohttp-3.9.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:70907533db712f7aa791effb38efa96f044ce3d4e850e2d7691abd759f4f0ae0"},
- {file = "aiohttp-3.9.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cdefe289681507187e375a5064c7599f52c40343a8701761c802c1853a504558"},
- {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7481f581251bb5558ba9f635db70908819caa221fc79ee52a7f58392778c636"},
- {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:49f0c1b3c2842556e5de35f122fc0f0b721334ceb6e78c3719693364d4af8499"},
- {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d406b01a9f5a7e232d1b0d161b40c05275ffbcbd772dc18c1d5a570961a1ca4"},
- {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d8e4450e7fe24d86e86b23cc209e0023177b6d59502e33807b732d2deb6975f"},
- {file = "aiohttp-3.9.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c0266cd6f005e99f3f51e583012de2778e65af6b73860038b968a0a8888487a"},
- {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab221850108a4a063c5b8a70f00dd7a1975e5a1713f87f4ab26a46e5feac5a0e"},
- {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c88a15f272a0ad3d7773cf3a37cc7b7d077cbfc8e331675cf1346e849d97a4e5"},
- {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:237533179d9747080bcaad4d02083ce295c0d2eab3e9e8ce103411a4312991a0"},
- {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:02ab6006ec3c3463b528374c4cdce86434e7b89ad355e7bf29e2f16b46c7dd6f"},
- {file = "aiohttp-3.9.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04fa38875e53eb7e354ece1607b1d2fdee2d175ea4e4d745f6ec9f751fe20c7c"},
- {file = "aiohttp-3.9.1-cp39-cp39-win32.whl", hash = "sha256:82eefaf1a996060602f3cc1112d93ba8b201dbf5d8fd9611227de2003dddb3b7"},
- {file = "aiohttp-3.9.1-cp39-cp39-win_amd64.whl", hash = "sha256:9b05d33ff8e6b269e30a7957bd3244ffbce2a7a35a81b81c382629b80af1a8bf"},
- {file = "aiohttp-3.9.1.tar.gz", hash = "sha256:8fc49a87ac269d4529da45871e2ffb6874e87779c3d0e2ccd813c0899221239d"},
-]
-
-[package.dependencies]
-aiodns = {version = "*", optional = true, markers = "(sys_platform == \"linux\" or sys_platform == \"darwin\") and extra == \"speedups\""}
-aiosignal = ">=1.1.2"
-attrs = ">=17.3.0"
-Brotli = {version = "*", optional = true, markers = "platform_python_implementation == \"CPython\" and extra == \"speedups\""}
-brotlicffi = {version = "*", optional = true, markers = "platform_python_implementation != \"CPython\" and extra == \"speedups\""}
-frozenlist = ">=1.1.1"
-multidict = ">=4.5,<7.0"
-yarl = ">=1.0,<2.0"
-
-[package.extras]
-speedups = ["Brotli", "aiodns", "brotlicffi"]
-
-[[package]]
-name = "aiosignal"
-version = "1.3.1"
-description = "aiosignal: a list of registered asynchronous callbacks"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"},
- {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"},
-]
-
-[package.dependencies]
-frozenlist = ">=1.1.0"
-
-[[package]]
-name = "argon2-cffi"
-version = "23.1.0"
-description = "Argon2 for Python"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"},
- {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"},
-]
-
-[package.dependencies]
-argon2-cffi-bindings = "*"
-
-[package.extras]
-dev = ["argon2-cffi[tests,typing]", "tox (>4)"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"]
-tests = ["hypothesis", "pytest"]
-typing = ["mypy"]
-
-[[package]]
-name = "argon2-cffi-bindings"
-version = "21.2.0"
-description = "Low-level CFFI bindings for Argon2"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"},
- {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"},
- {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"},
- {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"},
- {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"},
- {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"},
- {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"},
- {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"},
- {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"},
- {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"},
- {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"},
- {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"},
- {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"},
-]
-
-[package.dependencies]
-cffi = ">=1.0.1"
-
-[package.extras]
-dev = ["cogapp", "pre-commit", "pytest", "wheel"]
-tests = ["pytest"]
-
-[[package]]
-name = "asyncstdlib"
-version = "3.12.0"
-description = "The missing async toolbox"
-optional = false
-python-versions = "~=3.6"
-files = [
- {file = "asyncstdlib-3.12.0-py3-none-any.whl", hash = "sha256:68b8dc92d91193fe977825e2dc965b74ae6624d1994bcd5958aa7414ba9d4eaa"},
- {file = "asyncstdlib-3.12.0.tar.gz", hash = "sha256:83d620553fea73ee924a986e69135bcacb655f6cdc6f2f9e67030a1e259d8be5"},
-]
-
-[package.extras]
-doc = ["sphinx", "sphinxcontrib-trio"]
-test = ["black", "coverage", "flake8", "flake8-2020", "flake8-bugbear", "mypy", "pytest", "pytest-cov"]
-
-[[package]]
-name = "attrs"
-version = "23.2.0"
-description = "Classes Without Boilerplate"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"},
- {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"},
-]
-
-[package.extras]
-cov = ["attrs[tests]", "coverage[toml] (>=5.3)"]
-dev = ["attrs[tests]", "pre-commit"]
-docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"]
-tests = ["attrs[tests-no-zope]", "zope-interface"]
-tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"]
-tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"]
-
-[[package]]
-name = "beautifulsoup4"
-version = "4.12.2"
-description = "Screen-scraping library"
-optional = false
-python-versions = ">=3.6.0"
-files = [
- {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"},
- {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"},
-]
-
-[package.dependencies]
-soupsieve = ">1.2"
-
-[package.extras]
-html5lib = ["html5lib"]
-lxml = ["lxml"]
-
-[[package]]
-name = "brotli"
-version = "1.1.0"
-description = "Python bindings for the Brotli compression library"
-optional = false
-python-versions = "*"
-files = [
- {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e1140c64812cb9b06c922e77f1c26a75ec5e3f0fb2bf92cc8c58720dec276752"},
- {file = "Brotli-1.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c8fd5270e906eef71d4a8d19b7c6a43760c6abcfcc10c9101d14eb2357418de9"},
- {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ae56aca0402a0f9a3431cddda62ad71666ca9d4dc3a10a142b9dce2e3c0cda3"},
- {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:43ce1b9935bfa1ede40028054d7f48b5469cd02733a365eec8a329ffd342915d"},
- {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:7c4855522edb2e6ae7fdb58e07c3ba9111e7621a8956f481c68d5d979c93032e"},
- {file = "Brotli-1.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:38025d9f30cf4634f8309c6874ef871b841eb3c347e90b0851f63d1ded5212da"},
- {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e6a904cb26bfefc2f0a6f240bdf5233be78cd2488900a2f846f3c3ac8489ab80"},
- {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a37b8f0391212d29b3a91a799c8e4a2855e0576911cdfb2515487e30e322253d"},
- {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:e84799f09591700a4154154cab9787452925578841a94321d5ee8fb9a9a328f0"},
- {file = "Brotli-1.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f66b5337fa213f1da0d9000bc8dc0cb5b896b726eefd9c6046f699b169c41b9e"},
- {file = "Brotli-1.1.0-cp310-cp310-win32.whl", hash = "sha256:be36e3d172dc816333f33520154d708a2657ea63762ec16b62ece02ab5e4daf2"},
- {file = "Brotli-1.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:0c6244521dda65ea562d5a69b9a26120769b7a9fb3db2fe9545935ed6735b128"},
- {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a3daabb76a78f829cafc365531c972016e4aa8d5b4bf60660ad8ecee19df7ccc"},
- {file = "Brotli-1.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c8146669223164fc87a7e3de9f81e9423c67a79d6b3447994dfb9c95da16e2d6"},
- {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30924eb4c57903d5a7526b08ef4a584acc22ab1ffa085faceb521521d2de32dd"},
- {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ceb64bbc6eac5a140ca649003756940f8d6a7c444a68af170b3187623b43bebf"},
- {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a469274ad18dc0e4d316eefa616d1d0c2ff9da369af19fa6f3daa4f09671fd61"},
- {file = "Brotli-1.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:524f35912131cc2cabb00edfd8d573b07f2d9f21fa824bd3fb19725a9cf06327"},
- {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5b3cc074004d968722f51e550b41a27be656ec48f8afaeeb45ebf65b561481dd"},
- {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:19c116e796420b0cee3da1ccec3b764ed2952ccfcc298b55a10e5610ad7885f9"},
- {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:510b5b1bfbe20e1a7b3baf5fed9e9451873559a976c1a78eebaa3b86c57b4265"},
- {file = "Brotli-1.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a1fd8a29719ccce974d523580987b7f8229aeace506952fa9ce1d53a033873c8"},
- {file = "Brotli-1.1.0-cp311-cp311-win32.whl", hash = "sha256:39da8adedf6942d76dc3e46653e52df937a3c4d6d18fdc94a7c29d263b1f5b50"},
- {file = "Brotli-1.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:aac0411d20e345dc0920bdec5548e438e999ff68d77564d5e9463a7ca9d3e7b1"},
- {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
- {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:caf9ee9a5775f3111642d33b86237b05808dafcd6268faa492250e9b78046eb2"},
- {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70051525001750221daa10907c77830bc889cb6d865cc0b813d9db7fefc21451"},
- {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7f4bf76817c14aa98cc6697ac02f3972cb8c3da93e9ef16b9c66573a68014f91"},
- {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"},
- {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c3020404e0b5eefd7c9485ccf8393cfb75ec38ce75586e046573c9dc29967a0"},
- {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4ed11165dd45ce798d99a136808a794a748d5dc38511303239d4e2363c0695dc"},
- {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:4093c631e96fdd49e0377a9c167bfd75b6d0bad2ace734c6eb20b348bc3ea180"},
- {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:7e4c4629ddad63006efa0ef968c8e4751c5868ff0b1c5c40f76524e894c50248"},
- {file = "Brotli-1.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:861bf317735688269936f755fa136a99d1ed526883859f86e41a5d43c61d8966"},
- {file = "Brotli-1.1.0-cp312-cp312-win32.whl", hash = "sha256:5f4d5ea15c9382135076d2fb28dde923352fe02951e66935a9efaac8f10e81b0"},
- {file = "Brotli-1.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:906bc3a79de8c4ae5b86d3d75a8b77e44404b0f4261714306e3ad248d8ab0951"},
- {file = "Brotli-1.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:a090ca607cbb6a34b0391776f0cb48062081f5f60ddcce5d11838e67a01928d1"},
- {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2de9d02f5bda03d27ede52e8cfe7b865b066fa49258cbab568720aa5be80a47d"},
- {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2333e30a5e00fe0fe55903c8832e08ee9c3b1382aacf4db26664a16528d51b4b"},
- {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4d4a848d1837973bf0f4b5e54e3bec977d99be36a7895c61abb659301b02c112"},
- {file = "Brotli-1.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fdc3ff3bfccdc6b9cc7c342c03aa2400683f0cb891d46e94b64a197910dc4064"},
- {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5eeb539606f18a0b232d4ba45adccde4125592f3f636a6182b4a8a436548b914"},
- {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:fd5f17ff8f14003595ab414e45fce13d073e0762394f957182e69035c9f3d7c2"},
- {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:069a121ac97412d1fe506da790b3e69f52254b9df4eb665cd42460c837193354"},
- {file = "Brotli-1.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:e93dfc1a1165e385cc8239fab7c036fb2cd8093728cbd85097b284d7b99249a2"},
- {file = "Brotli-1.1.0-cp36-cp36m-win32.whl", hash = "sha256:a599669fd7c47233438a56936988a2478685e74854088ef5293802123b5b2460"},
- {file = "Brotli-1.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d143fd47fad1db3d7c27a1b1d66162e855b5d50a89666af46e1679c496e8e579"},
- {file = "Brotli-1.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:11d00ed0a83fa22d29bc6b64ef636c4552ebafcef57154b4ddd132f5638fbd1c"},
- {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f733d788519c7e3e71f0855c96618720f5d3d60c3cb829d8bbb722dddce37985"},
- {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:929811df5462e182b13920da56c6e0284af407d1de637d8e536c5cd00a7daf60"},
- {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0b63b949ff929fbc2d6d3ce0e924c9b93c9785d877a21a1b678877ffbbc4423a"},
- {file = "Brotli-1.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d192f0f30804e55db0d0e0a35d83a9fead0e9a359a9ed0285dbacea60cc10a84"},
- {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f296c40e23065d0d6650c4aefe7470d2a25fffda489bcc3eb66083f3ac9f6643"},
- {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:919e32f147ae93a09fe064d77d5ebf4e35502a8df75c29fb05788528e330fe74"},
- {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:23032ae55523cc7bccb4f6a0bf368cd25ad9bcdcc1990b64a647e7bbcce9cb5b"},
- {file = "Brotli-1.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:224e57f6eac61cc449f498cc5f0e1725ba2071a3d4f48d5d9dffba42db196438"},
- {file = "Brotli-1.1.0-cp37-cp37m-win32.whl", hash = "sha256:587ca6d3cef6e4e868102672d3bd9dc9698c309ba56d41c2b9c85bbb903cdb95"},
- {file = "Brotli-1.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2954c1c23f81c2eaf0b0717d9380bd348578a94161a65b3a2afc62c86467dd68"},
- {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:efa8b278894b14d6da122a72fefcebc28445f2d3f880ac59d46c90f4c13be9a3"},
- {file = "Brotli-1.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:03d20af184290887bdea3f0f78c4f737d126c74dc2f3ccadf07e54ceca3bf208"},
- {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6172447e1b368dcbc458925e5ddaf9113477b0ed542df258d84fa28fc45ceea7"},
- {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a743e5a28af5f70f9c080380a5f908d4d21d40e8f0e0c8901604d15cfa9ba751"},
- {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0541e747cce78e24ea12d69176f6a7ddb690e62c425e01d31cc065e69ce55b48"},
- {file = "Brotli-1.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:cdbc1fc1bc0bff1cef838eafe581b55bfbffaed4ed0318b724d0b71d4d377619"},
- {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:890b5a14ce214389b2cc36ce82f3093f96f4cc730c1cffdbefff77a7c71f2a97"},
- {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ab4fbee0b2d9098c74f3057b2bc055a8bd92ccf02f65944a241b4349229185a"},
- {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:141bd4d93984070e097521ed07e2575b46f817d08f9fa42b16b9b5f27b5ac088"},
- {file = "Brotli-1.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fce1473f3ccc4187f75b4690cfc922628aed4d3dd013d047f95a9b3919a86596"},
- {file = "Brotli-1.1.0-cp38-cp38-win32.whl", hash = "sha256:db85ecf4e609a48f4b29055f1e144231b90edc90af7481aa731ba2d059226b1b"},
- {file = "Brotli-1.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3d7954194c36e304e1523f55d7042c59dc53ec20dd4e9ea9d151f1b62b4415c0"},
- {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5fb2ce4b8045c78ebbc7b8f3c15062e435d47e7393cc57c25115cfd49883747a"},
- {file = "Brotli-1.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7905193081db9bfa73b1219140b3d315831cbff0d8941f22da695832f0dd188f"},
- {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a77def80806c421b4b0af06f45d65a136e7ac0bdca3c09d9e2ea4e515367c7e9"},
- {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dadd1314583ec0bf2d1379f7008ad627cd6336625d6679cf2f8e67081b83acf"},
- {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:901032ff242d479a0efa956d853d16875d42157f98951c0230f69e69f9c09bac"},
- {file = "Brotli-1.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:22fc2a8549ffe699bfba2256ab2ed0421a7b8fadff114a3d201794e45a9ff578"},
- {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ae15b066e5ad21366600ebec29a7ccbc86812ed267e4b28e860b8ca16a2bc474"},
- {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:949f3b7c29912693cee0afcf09acd6ebc04c57af949d9bf77d6101ebb61e388c"},
- {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:89f4988c7203739d48c6f806f1e87a1d96e0806d44f0fba61dba81392c9e474d"},
- {file = "Brotli-1.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:de6551e370ef19f8de1807d0a9aa2cdfdce2e85ce88b122fe9f6b2b076837e59"},
- {file = "Brotli-1.1.0-cp39-cp39-win32.whl", hash = "sha256:f0d8a7a6b5983c2496e364b969f0e526647a06b075d034f3297dc66f3b360c64"},
- {file = "Brotli-1.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:cdad5b9014d83ca68c25d2e9444e28e967ef16e80f6b436918c700c117a85467"},
- {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
-]
-
-[[package]]
-name = "brotlicffi"
-version = "1.1.0.0"
-description = "Python CFFI bindings to the Brotli library"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "brotlicffi-1.1.0.0-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:9b7ae6bd1a3f0df532b6d67ff674099a96d22bc0948955cb338488c31bfb8851"},
- {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19ffc919fa4fc6ace69286e0a23b3789b4219058313cf9b45625016bf7ff996b"},
- {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814"},
- {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84763dbdef5dd5c24b75597a77e1b30c66604725707565188ba54bab4f114820"},
- {file = "brotlicffi-1.1.0.0-cp37-abi3-win32.whl", hash = "sha256:1b12b50e07c3911e1efa3a8971543e7648100713d4e0971b13631cce22c587eb"},
- {file = "brotlicffi-1.1.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:994a4f0681bb6c6c3b0925530a1926b7a189d878e6e5e38fae8efa47c5d9c613"},
- {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2e4aeb0bd2540cb91b069dbdd54d458da8c4334ceaf2d25df2f4af576d6766ca"},
- {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b7b0033b0d37bb33009fb2fef73310e432e76f688af76c156b3594389d81391"},
- {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54a07bb2374a1eba8ebb52b6fafffa2afd3c4df85ddd38fcc0511f2bb387c2a8"},
- {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7901a7dc4b88f1c1475de59ae9be59799db1007b7d059817948d8e4f12e24e35"},
- {file = "brotlicffi-1.1.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:ce01c7316aebc7fce59da734286148b1d1b9455f89cf2c8a4dfce7d41db55c2d"},
- {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:246f1d1a90279bb6069de3de8d75a8856e073b8ff0b09dcca18ccc14cec85979"},
- {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc4bc5d82bc56ebd8b514fb8350cfac4627d6b0743382e46d033976a5f80fab6"},
- {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c26ecb14386a44b118ce36e546ce307f4810bc9598a6e6cb4f7fca725ae7e6"},
- {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca72968ae4eaf6470498d5c2887073f7efe3b1e7d7ec8be11a06a79cc810e990"},
- {file = "brotlicffi-1.1.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:add0de5b9ad9e9aa293c3aa4e9deb2b61e99ad6c1634e01d01d98c03e6a354cc"},
- {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9b6068e0f3769992d6b622a1cd2e7835eae3cf8d9da123d7f51ca9c1e9c333e5"},
- {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8557a8559509b61e65083f8782329188a250102372576093c88930c875a69838"},
- {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a7ae37e5d79c5bdfb5b4b99f2715a6035e6c5bf538c3746abc8e26694f92f33"},
- {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:391151ec86bb1c683835980f4816272a87eaddc46bb91cbf44f62228b84d8cca"},
- {file = "brotlicffi-1.1.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:2f3711be9290f0453de8eed5275d93d286abe26b08ab4a35d7452caa1fef532f"},
- {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1a807d760763e398bbf2c6394ae9da5815901aa93ee0a37bca5efe78d4ee3171"},
- {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa8ca0623b26c94fccc3a1fdd895be1743b838f3917300506d04aa3346fd2a14"},
- {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3de0cf28a53a3238b252aca9fed1593e9d36c1d116748013339f0949bfc84112"},
- {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6be5ec0e88a4925c91f3dea2bb0013b3a2accda6f77238f76a34a1ea532a1cb0"},
- {file = "brotlicffi-1.1.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d9eb71bb1085d996244439154387266fd23d6ad37161f6f52f1cd41dd95a3808"},
- {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
-]
-
-[package.dependencies]
-cffi = ">=1.0.0"
-
-[[package]]
-name = "bson"
-version = "0.5.10"
-description = "BSON codec for Python"
-optional = false
-python-versions = "*"
-files = [
- {file = "bson-0.5.10.tar.gz", hash = "sha256:d6511b2ab051139a9123c184de1a04227262173ad593429d21e443d6462d6590"},
-]
-
-[package.dependencies]
-python-dateutil = ">=2.4.0"
-six = ">=1.9.0"
-
-[[package]]
-name = "certifi"
-version = "2023.11.17"
-description = "Python package for providing Mozilla's CA Bundle."
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"},
- {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"},
-]
-
-[[package]]
-name = "cffi"
-version = "1.16.0"
-description = "Foreign Function Interface for Python calling C code."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"},
- {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"},
- {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"},
- {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"},
- {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"},
- {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"},
- {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"},
- {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"},
- {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"},
- {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"},
- {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"},
- {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"},
- {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"},
- {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"},
- {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"},
- {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"},
- {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"},
- {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"},
- {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"},
- {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"},
- {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"},
- {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"},
- {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"},
- {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"},
- {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"},
- {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"},
- {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"},
- {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"},
- {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"},
- {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"},
- {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"},
- {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"},
-]
-
-[package.dependencies]
-pycparser = "*"
-
-[[package]]
-name = "cryptography"
-version = "41.0.7"
-description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"},
- {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"},
- {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"},
- {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"},
- {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"},
- {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"},
- {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"},
- {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"},
- {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"},
- {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"},
- {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"},
- {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"},
- {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"},
- {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"},
- {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"},
- {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"},
- {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"},
- {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"},
- {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"},
- {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"},
- {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"},
- {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"},
- {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"},
-]
-
-[package.dependencies]
-cffi = ">=1.12"
-
-[package.extras]
-docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"]
-docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"]
-nox = ["nox"]
-pep8test = ["black", "check-sdist", "mypy", "ruff"]
-sdist = ["build"]
-ssh = ["bcrypt (>=3.1.5)"]
-test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"]
-test-randomorder = ["pytest-randomly"]
-
-[[package]]
-name = "cytoolz"
-version = "0.12.2"
-description = "Cython implementation of Toolz: High performance functional utilities"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "cytoolz-0.12.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bff49986c9bae127928a2f9fd6313146a342bfae8292f63e562f872bd01b871"},
- {file = "cytoolz-0.12.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:908c13f305d34322e11b796de358edaeea47dd2d115c33ca22909c5e8fb036fd"},
- {file = "cytoolz-0.12.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:735147aa41b8eeb104da186864b55e2a6623c758000081d19c93d759cd9523e3"},
- {file = "cytoolz-0.12.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d352d4de060604e605abdc5c8a5d0429d5f156cb9866609065d3003454d4cea"},
- {file = "cytoolz-0.12.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:89247ac220031a4f9f689688bcee42b38fd770d4cce294e5d914afc53b630abe"},
- {file = "cytoolz-0.12.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9070ae35c410d644e6df98a8f69f3ed2807e657d0df2a26b2643127cbf6944a5"},
- {file = "cytoolz-0.12.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:843500cd3e4884b92fd4037912bc42d5f047108d2c986d36352e880196d465b0"},
- {file = "cytoolz-0.12.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6a93644d7996fd696ab7f1f466cd75d718d0a00d5c8118b9fe8c64231dc1f85e"},
- {file = "cytoolz-0.12.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:96796594c770bc6587376e74ddc7d9c982d68f47116bb69d90873db5e0ea88b6"},
- {file = "cytoolz-0.12.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:48425107fbb1af3f0f2410c004f16be10ffc9374358e5600b57fa543f46f8def"},
- {file = "cytoolz-0.12.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:cde6dbb788a4cbc4a80a72aa96386ba4c2b17bdfff3ace0709799adbe16d6476"},
- {file = "cytoolz-0.12.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:68ae7091cc73a752f0b938f15bb193de80ca5edf5ae2ea6360d93d3e9228357b"},
- {file = "cytoolz-0.12.2-cp310-cp310-win32.whl", hash = "sha256:997b7e0960072f6bb445402da162f964ea67387b9f18bda2361edcc026e13597"},
- {file = "cytoolz-0.12.2-cp310-cp310-win_amd64.whl", hash = "sha256:663911786dcde3e4a5d88215c722c531c7548903dc07d418418c0d1c768072c0"},
- {file = "cytoolz-0.12.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a7d8b869ded171f6cdf584fc2fc6ae03b30a0e1e37a9daf213a59857a62ed90"},
- {file = "cytoolz-0.12.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9b28787eaf2174e68f0acb3c66f9c6b98bdfeb0930c0d0b08e1941c7aedc8d27"},
- {file = "cytoolz-0.12.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00547da587f124b32b072ce52dd5e4b37cf199fedcea902e33c67548523e4678"},
- {file = "cytoolz-0.12.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:275d53fd769df2102d6c9fc98e553bd8a9a38926f54d6b20cf29f0dd00bf3b75"},
- {file = "cytoolz-0.12.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5556acde785a61d4cf8b8534ae109b023cbd2f9df65ee2afbe070be47c410f8c"},
- {file = "cytoolz-0.12.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b41a85b9b9a2530b72b0d3d10e383fc3c2647ae88169d557d5e216f881860318"},
- {file = "cytoolz-0.12.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:673d6e9e3aa86949343b46ac2b7be266c36e07ce77fa1d40f349e6987a814d6e"},
- {file = "cytoolz-0.12.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81e6a9a8fda78a2f4901d2915b25bf620f372997ca1f20a14f7cefef5ad6f6f4"},
- {file = "cytoolz-0.12.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fa44215bc31675a6380cd896dadb7f2054a7b94cfb87e53e52af844c65406a54"},
- {file = "cytoolz-0.12.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:a08b4346350660799d81d4016e748bcb134a9083301d41f9618f64a6077f89f2"},
- {file = "cytoolz-0.12.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2fb740482794a72e2e5fec58e4d9b00dcd5a60a8cef68431ff12f2ba0e0d9a7e"},
- {file = "cytoolz-0.12.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9007bb1290c79402be6b84bcf9e7a622a073859d61fcee146dc7bc47afe328f3"},
- {file = "cytoolz-0.12.2-cp311-cp311-win32.whl", hash = "sha256:a973f5286758f76824ecf19ae1999f6697371a9121c8f163295d181d19a819d7"},
- {file = "cytoolz-0.12.2-cp311-cp311-win_amd64.whl", hash = "sha256:1ce324d1b413636ea5ee929f79637821f13c9e55e9588f38228947294944d2ed"},
- {file = "cytoolz-0.12.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c08094b9e5d1b6dfb0845a0253cc2655ca64ce70d15162dfdb102e28c8993493"},
- {file = "cytoolz-0.12.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baf020f4b708f800b353259cd7575e335a79f1ac912d9dda55b2aa0bf3616e42"},
- {file = "cytoolz-0.12.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4416ee86a87180b6a28e7483102c92debc077bec59c67eda8cc63fc52a218ac0"},
- {file = "cytoolz-0.12.2-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6ee222671eed5c5b16a5ad2aea07f0a715b8b199ee534834bc1dd2798f1ade7"},
- {file = "cytoolz-0.12.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad92e37be0b106fdbc575a3a669b43b364a5ef334495c9764de4c2d7541f7a99"},
- {file = "cytoolz-0.12.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:460c05238fbfe6d848141669d17a751a46c923f9f0c9fd8a3a462ab737623a44"},
- {file = "cytoolz-0.12.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9e5075e30be626ef0f9bedf7a15f55ed4d7209e832bc314fdc232dbd61dcbf44"},
- {file = "cytoolz-0.12.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:03b58f843f09e73414e82e57f7e8d88f087eaabf8f276b866a40661161da6c51"},
- {file = "cytoolz-0.12.2-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:5e4e612b7ecc9596e7c859cd9e0cd085e6d0c576b4f0d917299595eb56bf9c05"},
- {file = "cytoolz-0.12.2-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:08a0e03f287e45eb694998bb55ac1643372199c659affa8319dfbbdec7f7fb3c"},
- {file = "cytoolz-0.12.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b029bdd5a8b6c9a7c0e8fdbe4fc25ffaa2e09b77f6f3462314696e3a20511829"},
- {file = "cytoolz-0.12.2-cp36-cp36m-win32.whl", hash = "sha256:18580d060fa637ff01541640ecde6de832a248df02b8fb57e6dd578f189d62c7"},
- {file = "cytoolz-0.12.2-cp36-cp36m-win_amd64.whl", hash = "sha256:97cf514a9f3426228d8daf880f56488330e4b2948a6d183a106921217850d9eb"},
- {file = "cytoolz-0.12.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:18a0f838677f9510aef0330c0096778dd6406d21d4ff9504bf79d85235a18460"},
- {file = "cytoolz-0.12.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb081b2b02bf4405c804de1ece6f904916838ab0e057f1446e4ac12fac827960"},
- {file = "cytoolz-0.12.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:57233e1600560ceb719bed759dc78393edd541b9a3e7fefc3079abd83c26a6ea"},
- {file = "cytoolz-0.12.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0295289c4510efa41174850e75bc9188f82b72b1b54d0ea57d1781729c2924d5"},
- {file = "cytoolz-0.12.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a92aab8dd1d427ac9bc7480cfd3481dbab0ef024558f2f5a47de672d8a5ffaa"},
- {file = "cytoolz-0.12.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:51d3495235af09f21aa92a7cdd51504bda640b108b6be834448b774f52852c09"},
- {file = "cytoolz-0.12.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f9c690b359f503f18bf1c46a6456370e4f6f3fc4320b8774ae69c4f85ecc6c94"},
- {file = "cytoolz-0.12.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:481e3129a76ea01adcc0e7097ccb8dbddab1cfc40b6f0e32c670153512957c0f"},
- {file = "cytoolz-0.12.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:55e94124af9c8fbb1df54195cc092688fdad0765641b738970b6f1d5ea72e776"},
- {file = "cytoolz-0.12.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5616d386dfbfba7c39e9418ba668c734f6ceaacc0130877e8a100cad11e6838b"},
- {file = "cytoolz-0.12.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:732d08228fa8d366fec284f7032cc868d28a99fa81fc71e3adf7ecedbcf33a0f"},
- {file = "cytoolz-0.12.2-cp37-cp37m-win32.whl", hash = "sha256:f039c5373f7b314b151432c73219216857b19ab9cb834f0eb5d880f74fc7851c"},
- {file = "cytoolz-0.12.2-cp37-cp37m-win_amd64.whl", hash = "sha256:246368e983eaee9851b15d7755f82030eab4aa82098d2a34f6bef9c689d33fcc"},
- {file = "cytoolz-0.12.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:81074edf3c74bc9bd250d223408a5df0ff745d1f7a462597536cd26b9390e2d6"},
- {file = "cytoolz-0.12.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:960d85ebaa974ecea4e71fa56d098378fa51fd670ee744614cbb95bf95e28fc7"},
- {file = "cytoolz-0.12.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c8d0dff4865da54ae825d43e1721925721b19f3b9aca8e730c2ce73dee2c630"},
- {file = "cytoolz-0.12.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0a9d12436fd64937bd2c9609605f527af7f1a8db6e6637639b44121c0fe715d6"},
- {file = "cytoolz-0.12.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd461e402e24929d866f05061d2f8337e3a8456e75e21b72c125abff2477c7f7"},
- {file = "cytoolz-0.12.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0568d4da0a9ee9f9f5ab318f6501557f1cfe26d18c96c8e0dac7332ae04c6717"},
- {file = "cytoolz-0.12.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:101b5bd32badfc8b1f9c7be04ba3ae04fb47f9c8736590666ce9449bff76e0b1"},
- {file = "cytoolz-0.12.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8bb624dbaef4661f5e3625c1e39ad98ecceef281d1380e2774d8084ad0810275"},
- {file = "cytoolz-0.12.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3e993804e6b04113d61fdb9541b6df2f096ec265a506dad7437517470919c90f"},
- {file = "cytoolz-0.12.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:ab911033e5937fc221a2c165acce7f66ae5ac9d3e54bec56f3c9c197a96be574"},
- {file = "cytoolz-0.12.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:e6de6a4bdfaee382c2de2a3580b3ae76fce6105da202bbd835e5efbeae6a9c6e"},
- {file = "cytoolz-0.12.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9480b4b327be83c4d29cb88bcace761b11f5e30198ffe2287889455c6819e934"},
- {file = "cytoolz-0.12.2-cp38-cp38-win32.whl", hash = "sha256:4180b2785d1278e6abb36a72ac97c92432db53fa2df00ee943d2c15a33627d31"},
- {file = "cytoolz-0.12.2-cp38-cp38-win_amd64.whl", hash = "sha256:d0086ba8d41d73647b13087a3ca9c020f6bfec338335037e8f5172b4c7c8dce5"},
- {file = "cytoolz-0.12.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d29988bde28a90a00367edcf92afa1a2f7ecf43ea3ae383291b7da6d380ccc25"},
- {file = "cytoolz-0.12.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:24c0d71e9ac91f4466b1bd280f7de43aa4d94682daaf34d85d867a9b479b87cc"},
- {file = "cytoolz-0.12.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fa436abd4ac9ca71859baf5794614e6ec8fa27362f0162baedcc059048da55f7"},
- {file = "cytoolz-0.12.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45c7b4eac7571707269ebc2893facdf87e359cd5c7cfbfa9e6bd8b33fb1079c5"},
- {file = "cytoolz-0.12.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:294d24edc747ef4e1b28e54365f713becb844e7898113fafbe3e9165dc44aeea"},
- {file = "cytoolz-0.12.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:478051e5ef8278b2429864c8d148efcebdc2be948a61c9a44757cd8c816c98f5"},
- {file = "cytoolz-0.12.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:14108cafb140dd68fdda610c2bbc6a37bf052cd48cfebf487ed44145f7a2b67f"},
- {file = "cytoolz-0.12.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5fef7b602ccf8a3c77ab483479ccd7a952a8c5bb1c263156671ba7aaa24d1035"},
- {file = "cytoolz-0.12.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9bf51354e15520715f068853e6ab8190e77139940e8b8b633bdb587956a08fb0"},
- {file = "cytoolz-0.12.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:388f840fd911d61a96e9e595eaf003f9dc39e847c9060b8e623ab29e556f009b"},
- {file = "cytoolz-0.12.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:a67f75cc51a2dc7229a8ac84291e4d61dc5abfc8940befcf37a2836d95873340"},
- {file = "cytoolz-0.12.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:63b31345e20afda2ae30dba246955517a4264464d75e071fc2fa641e88c763ec"},
- {file = "cytoolz-0.12.2-cp39-cp39-win32.whl", hash = "sha256:f6e86ac2b45a95f75c6f744147483e0fc9697ce7dfe1726083324c236f873f8b"},
- {file = "cytoolz-0.12.2-cp39-cp39-win_amd64.whl", hash = "sha256:5998f81bf6a2b28a802521efe14d9fc119f74b64e87b62ad1b0e7c3d8366d0c7"},
- {file = "cytoolz-0.12.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:593e89e2518eaf81e96edcc9ef2c5fca666e8fc922b03d5cb7a7b8964dbee336"},
- {file = "cytoolz-0.12.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ff451d614ca1d4227db0ffa627fb51df71968cf0d9baf0210528dad10fdbc3ab"},
- {file = "cytoolz-0.12.2-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad9ea4a50d2948738351790047d45f2b1a023facc01bf0361988109b177e8b2f"},
- {file = "cytoolz-0.12.2-pp37-pypy37_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbe038bb78d599b5a29d09c438905defaa615a522bc7e12f8016823179439497"},
- {file = "cytoolz-0.12.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d494befe648c13c98c0f3d56d05489c839c9228a32f58e9777305deb6c2c1cee"},
- {file = "cytoolz-0.12.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c26805b6c8dc8565ed91045c44040bf6c0fe5cb5b390c78cd1d9400d08a6cd39"},
- {file = "cytoolz-0.12.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df4e32badb2ccf1773e1e74020b7e3b8caf9e92f842c6be7d14888ecdefc2c6c"},
- {file = "cytoolz-0.12.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce7889dc3701826d519ede93cdff11940fb5567dbdc165dce0e78047eece02b7"},
- {file = "cytoolz-0.12.2-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c820608e7077416f766b148d75e158e454881961881b657cff808529d261dd24"},
- {file = "cytoolz-0.12.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:698da4fa1f7baeea0607738cb1f9877ed1ba50342b29891b0223221679d6f729"},
- {file = "cytoolz-0.12.2.tar.gz", hash = "sha256:31d4b0455d72d914645f803d917daf4f314d115c70de0578d3820deb8b101f66"},
-]
-
-[package.dependencies]
-toolz = ">=0.8.0"
-
-[package.extras]
-cython = ["cython"]
-
-[[package]]
-name = "deprecated"
-version = "1.2.14"
-description = "Python @deprecated decorator to deprecate old python classes, functions or methods."
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"},
- {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"},
-]
-
-[package.dependencies]
-wrapt = ">=1.10,<2"
-
-[package.extras]
-dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"]
-
-[[package]]
-name = "fastpbkdf2"
-version = "0.2"
-description = "A faster implementation of PBKDF2"
-optional = false
-python-versions = "*"
-files = [
- {file = "fastpbkdf2-0.2.tar.gz", hash = "sha256:88fe92e9c3b6972421ba744ff4792334e4855b2d37534417f8c98c7cdba5ea9a"},
-]
-
-[package.dependencies]
-cffi = ">=1.1"
-six = ">=1.4.1"
-
-[[package]]
-name = "frozenlist"
-version = "1.4.1"
-description = "A list-like structure which implements collections.abc.MutableSequence"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"},
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"},
- {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"},
- {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"},
- {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"},
- {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"},
- {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"},
- {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"},
- {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"},
- {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"},
- {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"},
- {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"},
- {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"},
- {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"},
- {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"},
- {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"},
- {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"},
- {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"},
- {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"},
- {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"},
- {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"},
- {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"},
- {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"},
- {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"},
- {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"},
- {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"},
- {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"},
- {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"},
- {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"},
-]
-
-[[package]]
-name = "greenlet"
-version = "3.0.3"
-description = "Lightweight in-process concurrent programming"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"},
- {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"},
- {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"},
- {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"},
- {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"},
- {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"},
- {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"},
- {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"},
- {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"},
- {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"},
- {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"},
- {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"},
- {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"},
- {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"},
- {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"},
- {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"},
- {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"},
- {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"},
- {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"},
- {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"},
- {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"},
- {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"},
- {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"},
- {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"},
- {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"},
- {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"},
- {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"},
- {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"},
- {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"},
- {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"},
- {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"},
- {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"},
- {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"},
- {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"},
-]
-
-[package.extras]
-docs = ["Sphinx", "furo"]
-test = ["objgraph", "psutil"]
-
-[[package]]
-name = "html5tagger"
-version = "1.3.0"
-description = "Pythonic HTML generation/templating (no template files)"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "html5tagger-1.3.0-py3-none-any.whl", hash = "sha256:ce14313515edffec8ed8a36c5890d023922641171b4e6e5774ad1a74998f5351"},
- {file = "html5tagger-1.3.0.tar.gz", hash = "sha256:84fa3dfb49e5c83b79bbd856ab7b1de8e2311c3bb46a8be925f119e3880a8da9"},
-]
-
-[[package]]
-name = "httptools"
-version = "0.6.1"
-description = "A collection of framework independent HTTP protocol utils."
-optional = false
-python-versions = ">=3.8.0"
-files = [
- {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d2f6c3c4cb1948d912538217838f6e9960bc4a521d7f9b323b3da579cd14532f"},
- {file = "httptools-0.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563"},
- {file = "httptools-0.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639dc4f381a870c9ec860ce5c45921db50205a37cc3334e756269736ff0aac58"},
- {file = "httptools-0.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185"},
- {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ac5a0ae3d9f4fe004318d64b8a854edd85ab76cffbf7ef5e32920faef62f142"},
- {file = "httptools-0.6.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3f30d3ce413088a98b9db71c60a6ada2001a08945cb42dd65a9a9fe228627658"},
- {file = "httptools-0.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:1ed99a373e327f0107cb513b61820102ee4f3675656a37a50083eda05dc9541b"},
- {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7a7ea483c1a4485c71cb5f38be9db078f8b0e8b4c4dc0210f531cdd2ddac1ef1"},
- {file = "httptools-0.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:85ed077c995e942b6f1b07583e4eb0a8d324d418954fc6af913d36db7c05a5a0"},
- {file = "httptools-0.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b0bb634338334385351a1600a73e558ce619af390c2b38386206ac6a27fecfc"},
- {file = "httptools-0.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d9ceb2c957320def533671fc9c715a80c47025139c8d1f3797477decbc6edd2"},
- {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:4f0f8271c0a4db459f9dc807acd0eadd4839934a4b9b892f6f160e94da309837"},
- {file = "httptools-0.6.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6a4f5ccead6d18ec072ac0b84420e95d27c1cdf5c9f1bc8fbd8daf86bd94f43d"},
- {file = "httptools-0.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:5cceac09f164bcba55c0500a18fe3c47df29b62353198e4f37bbcc5d591172c3"},
- {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:75c8022dca7935cba14741a42744eee13ba05db00b27a4b940f0d646bd4d56d0"},
- {file = "httptools-0.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:48ed8129cd9a0d62cf4d1575fcf90fb37e3ff7d5654d3a5814eb3d55f36478c2"},
- {file = "httptools-0.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f58e335a1402fb5a650e271e8c2d03cfa7cea46ae124649346d17bd30d59c90"},
- {file = "httptools-0.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93ad80d7176aa5788902f207a4e79885f0576134695dfb0fefc15b7a4648d503"},
- {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9bb68d3a085c2174c2477eb3ffe84ae9fb4fde8792edb7bcd09a1d8467e30a84"},
- {file = "httptools-0.6.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b512aa728bc02354e5ac086ce76c3ce635b62f5fbc32ab7082b5e582d27867bb"},
- {file = "httptools-0.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:97662ce7fb196c785344d00d638fc9ad69e18ee4bfb4000b35a52efe5adcc949"},
- {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8e216a038d2d52ea13fdd9b9c9c7459fb80d78302b257828285eca1c773b99b3"},
- {file = "httptools-0.6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3e802e0b2378ade99cd666b5bffb8b2a7cc8f3d28988685dc300469ea8dd86cb"},
- {file = "httptools-0.6.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bd3e488b447046e386a30f07af05f9b38d3d368d1f7b4d8f7e10af85393db97"},
- {file = "httptools-0.6.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3"},
- {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3c3b214ce057c54675b00108ac42bacf2ab8f85c58e3f324a4e963bbc46424f4"},
- {file = "httptools-0.6.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ae5b97f690badd2ca27cbf668494ee1b6d34cf1c464271ef7bfa9ca6b83ffaf"},
- {file = "httptools-0.6.1-cp38-cp38-win_amd64.whl", hash = "sha256:405784577ba6540fa7d6ff49e37daf104e04f4b4ff2d1ac0469eaa6a20fde084"},
- {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:95fb92dd3649f9cb139e9c56604cc2d7c7bf0fc2e7c8d7fbd58f96e35eddd2a3"},
- {file = "httptools-0.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dcbab042cc3ef272adc11220517278519adf8f53fd3056d0e68f0a6f891ba94e"},
- {file = "httptools-0.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf2372e98406efb42e93bfe10f2948e467edfd792b015f1b4ecd897903d3e8d"},
- {file = "httptools-0.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:678fcbae74477a17d103b7cae78b74800d795d702083867ce160fc202104d0da"},
- {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:e0b281cf5a125c35f7f6722b65d8542d2e57331be573e9e88bc8b0115c4a7a81"},
- {file = "httptools-0.6.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:95658c342529bba4e1d3d2b1a874db16c7cca435e8827422154c9da76ac4e13a"},
- {file = "httptools-0.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ebaec1bf683e4bf5e9fbb49b8cc36da482033596a415b3e4ebab5a4c0d7ec5e"},
- {file = "httptools-0.6.1.tar.gz", hash = "sha256:c6e26c30455600b95d94b1b836085138e82f177351454ee841c148f93a9bad5a"},
-]
-
-[package.extras]
-test = ["Cython (>=0.29.24,<0.30.0)"]
-
-[[package]]
-name = "idna"
-version = "3.6"
-description = "Internationalized Domain Names in Applications (IDNA)"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"},
- {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"},
-]
-
-[[package]]
-name = "importlib-resources"
-version = "6.1.1"
-description = "Read resources from Python packages"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"},
- {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"},
-]
-
-[package.extras]
-docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
-testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"]
-
-[[package]]
-name = "iso8601"
-version = "2.1.0"
-description = "Simple module to parse ISO 8601 dates"
-optional = false
-python-versions = ">=3.7,<4.0"
-files = [
- {file = "iso8601-2.1.0-py3-none-any.whl", hash = "sha256:aac4145c4dcb66ad8b648a02830f5e2ff6c24af20f4f482689be402db2429242"},
- {file = "iso8601-2.1.0.tar.gz", hash = "sha256:6b1d3829ee8921c4301998c909f7829fa9ed3cbdac0d3b16af2d743aed1ba8df"},
-]
-
-[[package]]
-name = "jinja2"
-version = "3.1.3"
-description = "A very fast and expressive template engine."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"},
- {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"},
-]
-
-[package.dependencies]
-MarkupSafe = ">=2.0"
-
-[package.extras]
-i18n = ["Babel (>=2.7)"]
-
-[[package]]
-name = "limits"
-version = "3.7.0"
-description = "Rate limiting utilities"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "limits-3.7.0-py3-none-any.whl", hash = "sha256:c528817b7fc15f3e86ad091ba3e40231f6430a91b753db864767684cda8a7f2e"},
- {file = "limits-3.7.0.tar.gz", hash = "sha256:124c6a04d2f4b20990fb1de019eec9474d6c1346c70d8fd0561609b86998b64a"},
-]
-
-[package.dependencies]
-deprecated = ">=1.2"
-importlib-resources = ">=1.3"
-packaging = ">=21,<24"
-typing-extensions = "*"
-
-[package.extras]
-all = ["aetcd", "coredis (>=3.4.0,<5)", "emcache (>=0.6.1)", "emcache (>=1)", "etcd3", "motor (>=3,<4)", "pymemcache (>3,<5.0.0)", "pymongo (>4.1,<5)", "redis (>3,!=4.5.2,!=4.5.3,<6.0.0)", "redis (>=4.2.0,!=4.5.2,!=4.5.3)"]
-async-etcd = ["aetcd"]
-async-memcached = ["emcache (>=0.6.1)", "emcache (>=1)"]
-async-mongodb = ["motor (>=3,<4)"]
-async-redis = ["coredis (>=3.4.0,<5)"]
-etcd = ["etcd3"]
-memcached = ["pymemcache (>3,<5.0.0)"]
-mongodb = ["pymongo (>4.1,<5)"]
-redis = ["redis (>3,!=4.5.2,!=4.5.3,<6.0.0)"]
-rediscluster = ["redis (>=4.2.0,!=4.5.2,!=4.5.3)"]
-
-[[package]]
-name = "lxml"
-version = "5.1.0"
-description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"},
- {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"},
- {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"},
- {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"},
- {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2befa20a13f1a75c751f47e00929fb3433d67eb9923c2c0b364de449121f447c"},
- {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22b7ee4c35f374e2c20337a95502057964d7e35b996b1c667b5c65c567d2252a"},
- {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf8443781533b8d37b295016a4b53c1494fa9a03573c09ca5104550c138d5c05"},
- {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"},
- {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"},
- {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"},
- {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"},
- {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"},
- {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"},
- {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"},
- {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af8920ce4a55ff41167ddbc20077f5698c2e710ad3353d32a07d3264f3a2021e"},
- {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cfced4a069003d8913408e10ca8ed092c49a7f6cefee9bb74b6b3e860683b45"},
- {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9e5ac3437746189a9b4121db2a7b86056ac8786b12e88838696899328fc44bb2"},
- {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"},
- {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"},
- {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"},
- {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"},
- {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"},
- {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"},
- {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"},
- {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16dd953fb719f0ffc5bc067428fc9e88f599e15723a85618c45847c96f11f431"},
- {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16018f7099245157564d7148165132c70adb272fb5a17c048ba70d9cc542a1a1"},
- {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82cd34f1081ae4ea2ede3d52f71b7be313756e99b4b5f829f89b12da552d3aa3"},
- {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19a1bc898ae9f06bccb7c3e1dfd73897ecbbd2c96afe9095a6026016e5ca97b8"},
- {file = "lxml-5.1.0-cp312-cp312-win32.whl", hash = "sha256:13521a321a25c641b9ea127ef478b580b5ec82aa2e9fc076c86169d161798b01"},
- {file = "lxml-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:1ad17c20e3666c035db502c78b86e58ff6b5991906e55bdbef94977700c72623"},
- {file = "lxml-5.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:24ef5a4631c0b6cceaf2dbca21687e29725b7c4e171f33a8f8ce23c12558ded1"},
- {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d2900b7f5318bc7ad8631d3d40190b95ef2aa8cc59473b73b294e4a55e9f30f"},
- {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:601f4a75797d7a770daed8b42b97cd1bb1ba18bd51a9382077a6a247a12aa38d"},
- {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4b68c961b5cc402cbd99cca5eb2547e46ce77260eb705f4d117fd9c3f932b95"},
- {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:afd825e30f8d1f521713a5669b63657bcfe5980a916c95855060048b88e1adb7"},
- {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:262bc5f512a66b527d026518507e78c2f9c2bd9eb5c8aeeb9f0eb43fcb69dc67"},
- {file = "lxml-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:e856c1c7255c739434489ec9c8aa9cdf5179785d10ff20add308b5d673bed5cd"},
- {file = "lxml-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c7257171bb8d4432fe9d6fdde4d55fdbe663a63636a17f7f9aaba9bcb3153ad7"},
- {file = "lxml-5.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9e240ae0ba96477682aa87899d94ddec1cc7926f9df29b1dd57b39e797d5ab5"},
- {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96f02ba1bcd330807fc060ed91d1f7a20853da6dd449e5da4b09bfcc08fdcf5"},
- {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3898ae2b58eeafedfe99e542a17859017d72d7f6a63de0f04f99c2cb125936"},
- {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61c5a7edbd7c695e54fca029ceb351fc45cd8860119a0f83e48be44e1c464862"},
- {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3aeca824b38ca78d9ee2ab82bd9883083d0492d9d17df065ba3b94e88e4d7ee6"},
- {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"},
- {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"},
- {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"},
- {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"},
- {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"},
- {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"},
- {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"},
- {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"},
- {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:98f3f020a2b736566c707c8e034945c02aa94e124c24f77ca097c446f81b01f1"},
- {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"},
- {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"},
- {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"},
- {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"},
- {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"},
- {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"},
- {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"},
- {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8b0c78e7aac24979ef09b7f50da871c2de2def043d468c4b41f512d831e912"},
- {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bcf86dfc8ff3e992fed847c077bd875d9e0ba2fa25d859c3a0f0f76f07f0c8d"},
- {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:49a9b4af45e8b925e1cd6f3b15bbba2c81e7dba6dce170c677c9cda547411e14"},
- {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:280f3edf15c2a967d923bcfb1f8f15337ad36f93525828b40a0f9d6c2ad24890"},
- {file = "lxml-5.1.0-cp39-cp39-win32.whl", hash = "sha256:ed7326563024b6e91fef6b6c7a1a2ff0a71b97793ac33dbbcf38f6005e51ff6e"},
- {file = "lxml-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8d7b4beebb178e9183138f552238f7e6613162a42164233e2bda00cb3afac58f"},
- {file = "lxml-5.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9bd0ae7cc2b85320abd5e0abad5ccee5564ed5f0cc90245d2f9a8ef330a8deae"},
- {file = "lxml-5.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c1d679df4361408b628f42b26a5d62bd3e9ba7f0c0e7969f925021554755aa"},
- {file = "lxml-5.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2ad3a8ce9e8a767131061a22cd28fdffa3cd2dc193f399ff7b81777f3520e372"},
- {file = "lxml-5.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:304128394c9c22b6569eba2a6d98392b56fbdfbad58f83ea702530be80d0f9df"},
- {file = "lxml-5.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d74fcaf87132ffc0447b3c685a9f862ffb5b43e70ea6beec2fb8057d5d2a1fea"},
- {file = "lxml-5.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8cf5877f7ed384dabfdcc37922c3191bf27e55b498fecece9fd5c2c7aaa34c33"},
- {file = "lxml-5.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:877efb968c3d7eb2dad540b6cabf2f1d3c0fbf4b2d309a3c141f79c7e0061324"},
- {file = "lxml-5.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f14a4fb1c1c402a22e6a341a24c1341b4a3def81b41cd354386dcb795f83897"},
- {file = "lxml-5.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:25663d6e99659544ee8fe1b89b1a8c0aaa5e34b103fab124b17fa958c4a324a6"},
- {file = "lxml-5.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8b9f19df998761babaa7f09e6bc169294eefafd6149aaa272081cbddc7ba4ca3"},
- {file = "lxml-5.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e53d7e6a98b64fe54775d23a7c669763451340c3d44ad5e3a3b48a1efbdc96f"},
- {file = "lxml-5.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c3cd1fc1dc7c376c54440aeaaa0dcc803d2126732ff5c6b68ccd619f2e64be4f"},
- {file = "lxml-5.1.0.tar.gz", hash = "sha256:3eea6ed6e6c918e468e693c41ef07f3c3acc310b70ddd9cc72d9ef84bc9564ca"},
-]
-
-[package.extras]
-cssselect = ["cssselect (>=0.7)"]
-html5 = ["html5lib"]
-htmlsoup = ["BeautifulSoup4"]
-source = ["Cython (>=3.0.7)"]
-
-[[package]]
-name = "markupsafe"
-version = "2.1.3"
-description = "Safely add untrusted strings to HTML/XML markup."
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"},
- {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"},
- {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"},
- {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"},
- {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"},
- {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"},
- {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"},
- {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"},
-]
-
-[[package]]
-name = "multidict"
-version = "6.0.4"
-description = "multidict implementation"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8"},
- {file = "multidict-6.0.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171"},
- {file = "multidict-6.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7"},
- {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b"},
- {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547"},
- {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569"},
- {file = "multidict-6.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93"},
- {file = "multidict-6.0.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98"},
- {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0"},
- {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988"},
- {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc"},
- {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0"},
- {file = "multidict-6.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5"},
- {file = "multidict-6.0.4-cp310-cp310-win32.whl", hash = "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8"},
- {file = "multidict-6.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc"},
- {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03"},
- {file = "multidict-6.0.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3"},
- {file = "multidict-6.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba"},
- {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9"},
- {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982"},
- {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe"},
- {file = "multidict-6.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710"},
- {file = "multidict-6.0.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c"},
- {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4"},
- {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a"},
- {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c"},
- {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed"},
- {file = "multidict-6.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461"},
- {file = "multidict-6.0.4-cp311-cp311-win32.whl", hash = "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636"},
- {file = "multidict-6.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0"},
- {file = "multidict-6.0.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78"},
- {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f"},
- {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603"},
- {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac"},
- {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9"},
- {file = "multidict-6.0.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2"},
- {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde"},
- {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe"},
- {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067"},
- {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87"},
- {file = "multidict-6.0.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d"},
- {file = "multidict-6.0.4-cp37-cp37m-win32.whl", hash = "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775"},
- {file = "multidict-6.0.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e"},
- {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c"},
- {file = "multidict-6.0.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161"},
- {file = "multidict-6.0.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11"},
- {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e"},
- {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d"},
- {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2"},
- {file = "multidict-6.0.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258"},
- {file = "multidict-6.0.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52"},
- {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660"},
- {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951"},
- {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60"},
- {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d"},
- {file = "multidict-6.0.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1"},
- {file = "multidict-6.0.4-cp38-cp38-win32.whl", hash = "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779"},
- {file = "multidict-6.0.4-cp38-cp38-win_amd64.whl", hash = "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480"},
- {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664"},
- {file = "multidict-6.0.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35"},
- {file = "multidict-6.0.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60"},
- {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706"},
- {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d"},
- {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca"},
- {file = "multidict-6.0.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1"},
- {file = "multidict-6.0.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449"},
- {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf"},
- {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063"},
- {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a"},
- {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176"},
- {file = "multidict-6.0.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95"},
- {file = "multidict-6.0.4-cp39-cp39-win32.whl", hash = "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313"},
- {file = "multidict-6.0.4-cp39-cp39-win_amd64.whl", hash = "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2"},
- {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"},
-]
-
-[[package]]
-name = "mypy"
-version = "1.8.0"
-description = "Optional static typing for Python"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"},
- {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"},
- {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"},
- {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"},
- {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"},
- {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"},
- {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"},
- {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"},
- {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"},
- {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"},
- {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"},
- {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"},
- {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"},
- {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"},
- {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"},
- {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"},
- {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"},
- {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"},
- {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"},
- {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"},
- {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"},
- {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"},
- {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"},
- {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"},
- {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"},
- {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"},
- {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"},
-]
-
-[package.dependencies]
-mypy-extensions = ">=1.0.0"
-typing-extensions = ">=4.1.0"
-
-[package.extras]
-dmypy = ["psutil (>=4.0)"]
-install-types = ["pip"]
-mypyc = ["setuptools (>=50)"]
-reports = ["lxml"]
-
-[[package]]
-name = "mypy-extensions"
-version = "1.0.0"
-description = "Type system extensions for programs checked with the mypy type checker."
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
- {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
-]
-
-[[package]]
-name = "packaging"
-version = "23.2"
-description = "Core utilities for Python packages"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"},
- {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"},
-]
-
-[[package]]
-name = "passlib"
-version = "1.7.4"
-description = "comprehensive password hashing framework supporting over 30 schemes"
-optional = false
-python-versions = "*"
-files = [
- {file = "passlib-1.7.4-py2.py3-none-any.whl", hash = "sha256:aa6bca462b8d8bda89c70b382f0c298a20b5560af6cbfa2dce410c0a2fb669f1"},
- {file = "passlib-1.7.4.tar.gz", hash = "sha256:defd50f72b65c5402ab2c573830a6978e5f202ad0d984793c8dde2c4152ebe04"},
-]
-
-[package.extras]
-argon2 = ["argon2-cffi (>=18.2.0)"]
-bcrypt = ["bcrypt (>=3.1.0)"]
-build-docs = ["cloud-sptheme (>=1.10.1)", "sphinx (>=1.6)", "sphinxcontrib-fulltoc (>=1.2.0)"]
-totp = ["cryptography"]
-
-[[package]]
-name = "pendulum"
-version = "3.0.0"
-description = "Python datetimes made easy"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pendulum-3.0.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2cf9e53ef11668e07f73190c805dbdf07a1939c3298b78d5a9203a86775d1bfd"},
- {file = "pendulum-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fb551b9b5e6059377889d2d878d940fd0bbb80ae4810543db18e6f77b02c5ef6"},
- {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c58227ac260d5b01fc1025176d7b31858c9f62595737f350d22124a9a3ad82d"},
- {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:60fb6f415fea93a11c52578eaa10594568a6716602be8430b167eb0d730f3332"},
- {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b69f6b4dbcb86f2c2fe696ba991e67347bcf87fe601362a1aba6431454b46bde"},
- {file = "pendulum-3.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:138afa9c373ee450ede206db5a5e9004fd3011b3c6bbe1e57015395cd076a09f"},
- {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:83d9031f39c6da9677164241fd0d37fbfc9dc8ade7043b5d6d62f56e81af8ad2"},
- {file = "pendulum-3.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0c2308af4033fa534f089595bcd40a95a39988ce4059ccd3dc6acb9ef14ca44a"},
- {file = "pendulum-3.0.0-cp310-none-win_amd64.whl", hash = "sha256:9a59637cdb8462bdf2dbcb9d389518c0263799189d773ad5c11db6b13064fa79"},
- {file = "pendulum-3.0.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3725245c0352c95d6ca297193192020d1b0c0f83d5ee6bb09964edc2b5a2d508"},
- {file = "pendulum-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6c035f03a3e565ed132927e2c1b691de0dbf4eb53b02a5a3c5a97e1a64e17bec"},
- {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597e66e63cbd68dd6d58ac46cb7a92363d2088d37ccde2dae4332ef23e95cd00"},
- {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99a0f8172e19f3f0c0e4ace0ad1595134d5243cf75985dc2233e8f9e8de263ca"},
- {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:77d8839e20f54706aed425bec82a83b4aec74db07f26acd039905d1237a5e1d4"},
- {file = "pendulum-3.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afde30e8146292b059020fbc8b6f8fd4a60ae7c5e6f0afef937bbb24880bdf01"},
- {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:660434a6fcf6303c4efd36713ca9212c753140107ee169a3fc6c49c4711c2a05"},
- {file = "pendulum-3.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dee9e5a48c6999dc1106eb7eea3e3a50e98a50651b72c08a87ee2154e544b33e"},
- {file = "pendulum-3.0.0-cp311-none-win_amd64.whl", hash = "sha256:d4cdecde90aec2d67cebe4042fd2a87a4441cc02152ed7ed8fb3ebb110b94ec4"},
- {file = "pendulum-3.0.0-cp311-none-win_arm64.whl", hash = "sha256:773c3bc4ddda2dda9f1b9d51fe06762f9200f3293d75c4660c19b2614b991d83"},
- {file = "pendulum-3.0.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:409e64e41418c49f973d43a28afe5df1df4f1dd87c41c7c90f1a63f61ae0f1f7"},
- {file = "pendulum-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a38ad2121c5ec7c4c190c7334e789c3b4624798859156b138fcc4d92295835dc"},
- {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fde4d0b2024b9785f66b7f30ed59281bd60d63d9213cda0eb0910ead777f6d37"},
- {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b2c5675769fb6d4c11238132962939b960fcb365436b6d623c5864287faa319"},
- {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8af95e03e066826f0f4c65811cbee1b3123d4a45a1c3a2b4fc23c4b0dff893b5"},
- {file = "pendulum-3.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2165a8f33cb15e06c67070b8afc87a62b85c5a273e3aaa6bc9d15c93a4920d6f"},
- {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ad5e65b874b5e56bd942546ea7ba9dd1d6a25121db1c517700f1c9de91b28518"},
- {file = "pendulum-3.0.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:17fe4b2c844bbf5f0ece69cfd959fa02957c61317b2161763950d88fed8e13b9"},
- {file = "pendulum-3.0.0-cp312-none-win_amd64.whl", hash = "sha256:78f8f4e7efe5066aca24a7a57511b9c2119f5c2b5eb81c46ff9222ce11e0a7a5"},
- {file = "pendulum-3.0.0-cp312-none-win_arm64.whl", hash = "sha256:28f49d8d1e32aae9c284a90b6bb3873eee15ec6e1d9042edd611b22a94ac462f"},
- {file = "pendulum-3.0.0-cp37-cp37m-macosx_10_12_x86_64.whl", hash = "sha256:d4e2512f4e1a4670284a153b214db9719eb5d14ac55ada5b76cbdb8c5c00399d"},
- {file = "pendulum-3.0.0-cp37-cp37m-macosx_11_0_arm64.whl", hash = "sha256:3d897eb50883cc58d9b92f6405245f84b9286cd2de6e8694cb9ea5cb15195a32"},
- {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e169cc2ca419517f397811bbe4589cf3cd13fca6dc38bb352ba15ea90739ebb"},
- {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f17c3084a4524ebefd9255513692f7e7360e23c8853dc6f10c64cc184e1217ab"},
- {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:826d6e258052715f64d05ae0fc9040c0151e6a87aae7c109ba9a0ed930ce4000"},
- {file = "pendulum-3.0.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2aae97087872ef152a0c40e06100b3665d8cb86b59bc8471ca7c26132fccd0f"},
- {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ac65eeec2250d03106b5e81284ad47f0d417ca299a45e89ccc69e36130ca8bc7"},
- {file = "pendulum-3.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a5346d08f3f4a6e9e672187faa179c7bf9227897081d7121866358af369f44f9"},
- {file = "pendulum-3.0.0-cp37-none-win_amd64.whl", hash = "sha256:235d64e87946d8f95c796af34818c76e0f88c94d624c268693c85b723b698aa9"},
- {file = "pendulum-3.0.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:6a881d9c2a7f85bc9adafcfe671df5207f51f5715ae61f5d838b77a1356e8b7b"},
- {file = "pendulum-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:d7762d2076b9b1cb718a6631ad6c16c23fc3fac76cbb8c454e81e80be98daa34"},
- {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e8e36a8130819d97a479a0e7bf379b66b3b1b520e5dc46bd7eb14634338df8c"},
- {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7dc843253ac373358ffc0711960e2dd5b94ab67530a3e204d85c6e8cb2c5fa10"},
- {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a78ad3635d609ceb1e97d6aedef6a6a6f93433ddb2312888e668365908c7120"},
- {file = "pendulum-3.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b30a137e9e0d1f751e60e67d11fc67781a572db76b2296f7b4d44554761049d6"},
- {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:c95984037987f4a457bb760455d9ca80467be792236b69d0084f228a8ada0162"},
- {file = "pendulum-3.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d29c6e578fe0f893766c0d286adbf0b3c726a4e2341eba0917ec79c50274ec16"},
- {file = "pendulum-3.0.0-cp38-none-win_amd64.whl", hash = "sha256:deaba8e16dbfcb3d7a6b5fabdd5a38b7c982809567479987b9c89572df62e027"},
- {file = "pendulum-3.0.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b11aceea5b20b4b5382962b321dbc354af0defe35daa84e9ff3aae3c230df694"},
- {file = "pendulum-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90d4d504e82ad236afac9adca4d6a19e4865f717034fc69bafb112c320dcc8f"},
- {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:825799c6b66e3734227756fa746cc34b3549c48693325b8b9f823cb7d21b19ac"},
- {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad769e98dc07972e24afe0cff8d365cb6f0ebc7e65620aa1976fcfbcadc4c6f3"},
- {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6fc26907eb5fb8cc6188cc620bc2075a6c534d981a2f045daa5f79dfe50d512"},
- {file = "pendulum-3.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c717eab1b6d898c00a3e0fa7781d615b5c5136bbd40abe82be100bb06df7a56"},
- {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3ddd1d66d1a714ce43acfe337190be055cdc221d911fc886d5a3aae28e14b76d"},
- {file = "pendulum-3.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:822172853d7a9cf6da95d7b66a16c7160cb99ae6df55d44373888181d7a06edc"},
- {file = "pendulum-3.0.0-cp39-none-win_amd64.whl", hash = "sha256:840de1b49cf1ec54c225a2a6f4f0784d50bd47f68e41dc005b7f67c7d5b5f3ae"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3b1f74d1e6ffe5d01d6023870e2ce5c2191486928823196f8575dcc786e107b1"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:729e9f93756a2cdfa77d0fc82068346e9731c7e884097160603872686e570f07"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e586acc0b450cd21cbf0db6bae386237011b75260a3adceddc4be15334689a9a"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22e7944ffc1f0099a79ff468ee9630c73f8c7835cd76fdb57ef7320e6a409df4"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:fa30af36bd8e50686846bdace37cf6707bdd044e5cb6e1109acbad3277232e04"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:440215347b11914ae707981b9a57ab9c7b6983ab0babde07063c6ee75c0dc6e7"},
- {file = "pendulum-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:314c4038dc5e6a52991570f50edb2f08c339debdf8cea68ac355b32c4174e820"},
- {file = "pendulum-3.0.0-pp37-pypy37_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5acb1d386337415f74f4d1955c4ce8d0201978c162927d07df8eb0692b2d8533"},
- {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a789e12fbdefaffb7b8ac67f9d8f22ba17a3050ceaaa635cd1cc4645773a4b1e"},
- {file = "pendulum-3.0.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:860aa9b8a888e5913bd70d819306749e5eb488e6b99cd6c47beb701b22bdecf5"},
- {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:5ebc65ea033ef0281368217fbf59f5cb05b338ac4dd23d60959c7afcd79a60a0"},
- {file = "pendulum-3.0.0-pp37-pypy37_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:d9fef18ab0386ef6a9ac7bad7e43ded42c83ff7ad412f950633854f90d59afa8"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1c134ba2f0571d0b68b83f6972e2307a55a5a849e7dac8505c715c531d2a8795"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:385680812e7e18af200bb9b4a49777418c32422d05ad5a8eb85144c4a285907b"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eec91cd87c59fb32ec49eb722f375bd58f4be790cae11c1b70fac3ee4f00da0"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4386bffeca23c4b69ad50a36211f75b35a4deb6210bdca112ac3043deb7e494a"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:dfbcf1661d7146d7698da4b86e7f04814221081e9fe154183e34f4c5f5fa3bf8"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:04a1094a5aa1daa34a6b57c865b25f691848c61583fb22722a4df5699f6bf74c"},
- {file = "pendulum-3.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5b0ec85b9045bd49dd3a3493a5e7ddfd31c36a2a60da387c419fa04abcaecb23"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:0a15b90129765b705eb2039062a6daf4d22c4e28d1a54fa260892e8c3ae6e157"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:bb8f6d7acd67a67d6fedd361ad2958ff0539445ef51cbe8cd288db4306503cd0"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd69b15374bef7e4b4440612915315cc42e8575fcda2a3d7586a0d88192d0c88"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc00f8110db6898360c53c812872662e077eaf9c75515d53ecc65d886eec209a"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:83a44e8b40655d0ba565a5c3d1365d27e3e6778ae2a05b69124db9e471255c4a"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1a3604e9fbc06b788041b2a8b78f75c243021e0f512447806a6d37ee5214905d"},
- {file = "pendulum-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:92c307ae7accebd06cbae4729f0ba9fa724df5f7d91a0964b1b972a22baa482b"},
- {file = "pendulum-3.0.0.tar.gz", hash = "sha256:5d034998dea404ec31fae27af6b22cff1708f830a1ed7353be4d1019bb9f584e"},
-]
-
-[package.dependencies]
-python-dateutil = ">=2.6"
-tzdata = ">=2020.1"
-
-[package.extras]
-test = ["time-machine (>=2.6.0)"]
-
-[[package]]
-name = "py-buzz"
-version = "4.1.0"
-description = "\"That's not flying, it's falling with style\": Exceptions with extras"
-optional = false
-python-versions = ">=3.8,<4.0"
-files = [
- {file = "py_buzz-4.1.0-py3-none-any.whl", hash = "sha256:77dc0dc9c9923b6f8079dc2e2c3b4fbebd2308acaca1500f8eda2711cd308f97"},
- {file = "py_buzz-4.1.0.tar.gz", hash = "sha256:ac11dba4922b2af114126044597d2fcd15e8c6a74368bed91f3c6732c8f09812"},
-]
-
-[[package]]
-name = "pycares"
-version = "4.4.0"
-description = "Python interface for c-ares"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "pycares-4.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:24da119850841d16996713d9c3374ca28a21deee056d609fbbed29065d17e1f6"},
- {file = "pycares-4.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8f64cb58729689d4d0e78f0bfb4c25ce2f851d0274c0273ac751795c04b8798a"},
- {file = "pycares-4.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d33e2a1120887e89075f7f814ec144f66a6ce06a54f5722ccefc62fbeda83cff"},
- {file = "pycares-4.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c680fef1b502ee680f8f0b95a41af4ec2c234e50e16c0af5bbda31999d3584bd"},
- {file = "pycares-4.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fff16b09042ba077f7b8aa5868d1d22456f0002574d0ba43462b10a009331677"},
- {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:229a1675eb33bc9afb1fc463e73ee334950ccc485bc83a43f6ae5839fb4d5fa3"},
- {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3aebc73e5ad70464f998f77f2da2063aa617cbd8d3e8174dd7c5b4518f967153"},
- {file = "pycares-4.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6ef64649eba56448f65e26546d85c860709844d2fc22ef14d324fe0b27f761a9"},
- {file = "pycares-4.4.0-cp310-cp310-win32.whl", hash = "sha256:4afc2644423f4eef97857a9fd61be9758ce5e336b4b0bd3d591238bb4b8b03e0"},
- {file = "pycares-4.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:5ed4e04af4012f875b78219d34434a6d08a67175150ac1b79eb70ab585d4ba8c"},
- {file = "pycares-4.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:bce8db2fc6f3174bd39b81405210b9b88d7b607d33e56a970c34a0c190da0490"},
- {file = "pycares-4.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a0303428d013ccf5c51de59c83f9127aba6200adb7fd4be57eddb432a1edd2a"},
- {file = "pycares-4.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb91792f1556f97be7f7acb57dc7756d89c5a87bd8b90363a77dbf9ea653817"},
- {file = "pycares-4.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b61579cecf1f4d616e5ea31a6e423a16680ab0d3a24a2ffe7bb1d4ee162477ff"},
- {file = "pycares-4.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7af06968cbf6851566e806bf3e72825b0e6671832a2cbe840be1d2d65350710"},
- {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ceb12974367b0a68a05d52f4162b29f575d241bd53de155efe632bf2c943c7f6"},
- {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2eeec144bcf6a7b6f2d74d6e70cbba7886a84dd373c886f06cb137a07de4954c"},
- {file = "pycares-4.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e3a6f7cfdfd11eb5493d6d632e582408c8f3b429f295f8799c584c108b28db6f"},
- {file = "pycares-4.4.0-cp311-cp311-win32.whl", hash = "sha256:34736a2ffaa9c08ca9c707011a2d7b69074bbf82d645d8138bba771479b2362f"},
- {file = "pycares-4.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:eb66c30eb11e877976b7ead13632082a8621df648c408b8e15cdb91a452dd502"},
- {file = "pycares-4.4.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:fd644505a8cfd7f6584d33a9066d4e3d47700f050ef1490230c962de5dfb28c6"},
- {file = "pycares-4.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52084961262232ec04bd75f5043aed7e5d8d9695e542ff691dfef0110209f2d4"},
- {file = "pycares-4.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0c5368206057884cde18602580083aeaad9b860e2eac14fd253543158ce1e93"},
- {file = "pycares-4.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:112a4979c695b1c86f6782163d7dec58d57a3b9510536dcf4826550f9053dd9a"},
- {file = "pycares-4.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d186dafccdaa3409194c0f94db93c1a5d191145a275f19da6591f9499b8e7b8"},
- {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:64965dc19c578a683ea73487a215a8897276224e004d50eeb21f0bc7a0b63c88"},
- {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ed2a38e34bec6f2586435f6ff0bc5fe11d14bebd7ed492cf739a424e81681540"},
- {file = "pycares-4.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:94d6962db81541eb0396d2f0dfcbb18cdb8c8b251d165efc2d974ae652c547d4"},
- {file = "pycares-4.4.0-cp312-cp312-win32.whl", hash = "sha256:1168a48a834813aa80f412be2df4abaf630528a58d15c704857448b20b1675c0"},
- {file = "pycares-4.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:db24c4e7fea4a052c6e869cbf387dd85d53b9736cfe1ef5d8d568d1ca925e977"},
- {file = "pycares-4.4.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:21a5a0468861ec7df7befa69050f952da13db5427ae41ffe4713bc96291d1d95"},
- {file = "pycares-4.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22c00bf659a9fa44d7b405cf1cd69b68b9d37537899898d8cbe5dffa4016b273"},
- {file = "pycares-4.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23aa3993a352491a47fcf17867f61472f32f874df4adcbb486294bd9fbe8abee"},
- {file = "pycares-4.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:813d661cbe2e37d87da2d16b7110a6860e93ddb11735c6919c8a3545c7b9c8d8"},
- {file = "pycares-4.4.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77cf5a2fd5583c670de41a7f4a7b46e5cbabe7180d8029f728571f4d2e864084"},
- {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3eaa6681c0a3e3f3868c77aca14b7760fed35fdfda2fe587e15c701950e7bc69"},
- {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ad58e284a658a8a6a84af2e0b62f2f961f303cedfe551854d7bd40c3cbb61912"},
- {file = "pycares-4.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:bfb89ca9e3d0a9b5332deeb666b2ede9d3469107742158f4aeda5ce032d003f4"},
- {file = "pycares-4.4.0-cp38-cp38-win32.whl", hash = "sha256:f36bdc1562142e3695555d2f4ac0cb69af165eddcefa98efc1c79495b533481f"},
- {file = "pycares-4.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:902461a92b6a80fd5041a2ec5235680c7cc35e43615639ec2a40e63fca2dfb51"},
- {file = "pycares-4.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7bddc6adba8f699728f7fc1c9ce8cef359817ad78e2ed52b9502cb5f8dc7f741"},
- {file = "pycares-4.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cb49d5805cd347c404f928c5ae7c35e86ba0c58ffa701dbe905365e77ce7d641"},
- {file = "pycares-4.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56cf3349fa3a2e67ed387a7974c11d233734636fe19facfcda261b411af14d80"},
- {file = "pycares-4.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf2eaa83a5987e48fa63302f0fe7ce3275cfda87b34d40fef9ce703fb3ac002"},
- {file = "pycares-4.4.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82bba2ab77eb5addbf9758d514d9bdef3c1bfe7d1649a47bd9a0d55a23ef478b"},
- {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c6a8bde63106f162fca736e842a916853cad3c8d9d137e11c9ffa37efa818b02"},
- {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5f646eec041db6ffdbcaf3e0756fb92018f7af3266138c756bb09d2b5baadec"},
- {file = "pycares-4.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9dc04c54c6ea615210c1b9e803d0e2d2255f87a3d5d119b6482c8f0dfa15b26b"},
- {file = "pycares-4.4.0-cp39-cp39-win32.whl", hash = "sha256:97892cced5794d721fb4ff8765764aa4ea48fe8b2c3820677505b96b83d4ef47"},
- {file = "pycares-4.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:917f08f0b5d9324e9a34211e68d27447c552b50ab967044776bbab7e42a553a2"},
- {file = "pycares-4.4.0.tar.gz", hash = "sha256:f47579d508f2f56eddd16ce72045782ad3b1b3b678098699e2b6a1b30733e1c2"},
-]
-
-[package.dependencies]
-cffi = ">=1.5.0"
-
-[package.extras]
-idna = ["idna (>=2.1)"]
-
-[[package]]
-name = "pycparser"
-version = "2.21"
-description = "C parser in Python"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-files = [
- {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"},
- {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"},
-]
-
-[[package]]
-name = "pycryptodomex"
-version = "3.20.0"
-description = "Cryptographic library for Python"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
-files = [
- {file = "pycryptodomex-3.20.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:645bd4ca6f543685d643dadf6a856cc382b654cc923460e3a10a49c1b3832aeb"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ff5c9a67f8a4fba4aed887216e32cbc48f2a6fb2673bb10a99e43be463e15913"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:8ee606964553c1a0bc74057dd8782a37d1c2bc0f01b83193b6f8bb14523b877b"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7805830e0c56d88f4d491fa5ac640dfc894c5ec570d1ece6ed1546e9df2e98d6"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-musllinux_1_1_aarch64.whl", hash = "sha256:bc3ee1b4d97081260d92ae813a83de4d2653206967c4a0a017580f8b9548ddbc"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-win32.whl", hash = "sha256:8af1a451ff9e123d0d8bd5d5e60f8e3315c3a64f3cdd6bc853e26090e195cdc8"},
- {file = "pycryptodomex-3.20.0-cp27-cp27m-win_amd64.whl", hash = "sha256:cbe71b6712429650e3883dc81286edb94c328ffcd24849accac0a4dbcc76958a"},
- {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:76bd15bb65c14900d98835fcd10f59e5e0435077431d3a394b60b15864fddd64"},
- {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:653b29b0819605fe0898829c8ad6400a6ccde096146730c2da54eede9b7b8baa"},
- {file = "pycryptodomex-3.20.0-cp27-cp27mu-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a5ec91388984909bb5398ea49ee61b68ecb579123694bffa172c3b0a107079"},
- {file = "pycryptodomex-3.20.0-cp27-cp27mu-musllinux_1_1_aarch64.whl", hash = "sha256:108e5f1c1cd70ffce0b68739c75734437c919d2eaec8e85bffc2c8b4d2794305"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_universal2.whl", hash = "sha256:59af01efb011b0e8b686ba7758d59cf4a8263f9ad35911bfe3f416cee4f5c08c"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:82ee7696ed8eb9a82c7037f32ba9b7c59e51dda6f105b39f043b6ef293989cb3"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91852d4480a4537d169c29a9d104dda44094c78f1f5b67bca76c29a91042b623"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca649483d5ed251d06daf25957f802e44e6bb6df2e8f218ae71968ff8f8edc4"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e186342cfcc3aafaad565cbd496060e5a614b441cacc3995ef0091115c1f6c5"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:25cd61e846aaab76d5791d006497134602a9e451e954833018161befc3b5b9ed"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_i686.whl", hash = "sha256:9c682436c359b5ada67e882fec34689726a09c461efd75b6ea77b2403d5665b7"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7a7a8f33a1f1fb762ede6cc9cbab8f2a9ba13b196bfaf7bc6f0b39d2ba315a43"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-win32.whl", hash = "sha256:c39778fd0548d78917b61f03c1fa8bfda6cfcf98c767decf360945fe6f97461e"},
- {file = "pycryptodomex-3.20.0-cp35-abi3-win_amd64.whl", hash = "sha256:2a47bcc478741b71273b917232f521fd5704ab4b25d301669879e7273d3586cc"},
- {file = "pycryptodomex-3.20.0-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:1be97461c439a6af4fe1cf8bf6ca5936d3db252737d2f379cc6b2e394e12a458"},
- {file = "pycryptodomex-3.20.0-pp27-pypy_73-win32.whl", hash = "sha256:19764605feea0df966445d46533729b645033f134baeb3ea26ad518c9fdf212c"},
- {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:f2e497413560e03421484189a6b65e33fe800d3bd75590e6d78d4dfdb7accf3b"},
- {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e48217c7901edd95f9f097feaa0388da215ed14ce2ece803d3f300b4e694abea"},
- {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d00fe8596e1cc46b44bf3907354e9377aa030ec4cd04afbbf6e899fc1e2a7781"},
- {file = "pycryptodomex-3.20.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:88afd7a3af7ddddd42c2deda43d53d3dfc016c11327d0915f90ca34ebda91499"},
- {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d3584623e68a5064a04748fb6d76117a21a7cb5eaba20608a41c7d0c61721794"},
- {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0daad007b685db36d977f9de73f61f8da2a7104e20aca3effd30752fd56f73e1"},
- {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dcac11031a71348faaed1f403a0debd56bf5404232284cf8c761ff918886ebc"},
- {file = "pycryptodomex-3.20.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:69138068268127cd605e03438312d8f271135a33140e2742b417d027a0539427"},
- {file = "pycryptodomex-3.20.0.tar.gz", hash = "sha256:7a710b79baddd65b806402e14766c721aee8fb83381769c27920f26476276c1e"},
-]
-
-[[package]]
-name = "pydantic"
-version = "1.10.13"
-description = "Data validation and settings management using python type hints"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"},
- {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"},
- {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"},
- {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"},
- {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"},
- {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"},
- {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"},
- {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"},
- {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"},
- {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"},
- {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"},
- {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"},
- {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"},
- {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"},
- {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"},
- {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"},
- {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"},
- {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"},
- {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"},
- {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"},
- {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"},
- {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"},
- {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"},
- {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"},
- {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"},
- {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"},
- {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"},
- {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"},
- {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"},
- {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"},
- {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"},
- {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"},
- {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"},
- {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"},
- {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"},
- {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"},
-]
-
-[package.dependencies]
-typing-extensions = ">=4.2.0"
-
-[package.extras]
-dotenv = ["python-dotenv (>=0.10.4)"]
-email = ["email-validator (>=1.0.3)"]
-
-[[package]]
-name = "pyjwt"
-version = "2.8.0"
-description = "JSON Web Token implementation in Python"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "PyJWT-2.8.0-py3-none-any.whl", hash = "sha256:59127c392cc44c2da5bb3192169a91f429924e17aff6534d70fdc02ab3e04320"},
- {file = "PyJWT-2.8.0.tar.gz", hash = "sha256:57e28d156e3d5c10088e0c68abb90bfac3df82b40a71bd0daa20c65ccd5c23de"},
-]
-
-[package.extras]
-crypto = ["cryptography (>=3.4.0)"]
-dev = ["coverage[toml] (==5.0.4)", "cryptography (>=3.4.0)", "pre-commit", "pytest (>=6.0.0,<7.0.0)", "sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
-docs = ["sphinx (>=4.5.0,<5.0.0)", "sphinx-rtd-theme", "zope.interface"]
-tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"]
-
-[[package]]
-name = "pyseto"
-version = "1.7.7"
-description = "A Python implementation of PASETO/PASERK."
-optional = false
-python-versions = ">=3.8,<4.0"
-files = [
- {file = "pyseto-1.7.7-py3-none-any.whl", hash = "sha256:05dbb906a0b27bba22e28fc4289b7a7743b1d820fa2afaa79a25f6cef945014d"},
- {file = "pyseto-1.7.7.tar.gz", hash = "sha256:c0f1fe56c529f7001e93b6f646d4a47469ecee45df3fa749d467e8721f5b0f6e"},
-]
-
-[package.dependencies]
-argon2-cffi = ">=23.1.0,<24.0.0"
-cryptography = ">=41.0.5,<42"
-iso8601 = ">=1.0.2,<3.0.0"
-pycryptodomex = ">=3.18.0,<4.0.0"
-
-[package.extras]
-docs = ["Sphinx[docs] (>=6,<8)", "sphinx-autodoc-typehints[docs] (>=1.21.0,<2.0.0)", "sphinx-rtd-theme[docs] (>=1.2.1,<2.0.0)"]
-
-[[package]]
-name = "python-dateutil"
-version = "2.8.2"
-description = "Extensions to the standard Python datetime module"
-optional = false
-python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
-files = [
- {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"},
- {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"},
-]
-
-[package.dependencies]
-six = ">=1.5"
-
-[[package]]
-name = "pyyaml"
-version = "6.0.1"
-description = "YAML parser and emitter for Python"
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"},
- {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"},
- {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"},
- {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"},
- {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"},
- {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"},
- {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"},
- {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"},
- {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"},
- {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"},
- {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"},
- {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"},
- {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"},
- {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"},
- {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"},
- {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"},
- {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"},
- {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"},
- {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"},
- {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"},
- {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"},
- {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"},
- {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"},
- {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"},
- {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"},
- {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"},
- {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"},
- {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"},
- {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"},
- {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"},
- {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"},
- {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"},
- {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"},
-]
-
-[[package]]
-name = "sanic"
-version = "23.12.1"
-description = "A web server and web framework that's written to go fast. Build fast. Run fast."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "sanic-23.12.1-py3-none-any.whl", hash = "sha256:e292293b2663a7afeb380bdc48ab93978468b27deae46ad9561513941eb0311f"},
- {file = "sanic-23.12.1.tar.gz", hash = "sha256:2528ca81d2bdc58ea67d93c500df1a9c58404904b0bc3442425b464c72b4bb84"},
-]
-
-[package.dependencies]
-aiofiles = ">=0.6.0"
-html5tagger = ">=1.2.1"
-httptools = ">=0.0.10"
-multidict = ">=5.0,<7.0"
-sanic-ext = {version = "*", optional = true, markers = "extra == \"ext\""}
-sanic-routing = ">=23.12.0"
-tracerite = ">=1.0.0"
-typing-extensions = ">=4.4.0"
-ujson = {version = ">=1.35", markers = "sys_platform != \"win32\" and implementation_name == \"cpython\""}
-uvloop = {version = ">=0.15.0", markers = "sys_platform != \"win32\" and implementation_name == \"cpython\""}
-websockets = ">=10.0"
-
-[package.extras]
-all = ["autodocsumm (>=0.2.11)", "bandit", "beautifulsoup4", "chardet (==3.*)", "coverage", "cryptography", "docutils", "enum-tools[sphinx]", "m2r2", "mistune (<2.0.0)", "mypy", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "ruff", "sanic-testing (>=23.6.0)", "slotscheck (>=0.8.0,<1)", "sphinx (>=2.1.2)", "sphinx-rtd-theme (>=0.4.3)", "towncrier", "tox", "types-ujson", "uvicorn (<0.15.0)"]
-dev = ["bandit", "beautifulsoup4", "chardet (==3.*)", "coverage", "cryptography", "docutils", "mypy", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "ruff", "sanic-testing (>=23.6.0)", "slotscheck (>=0.8.0,<1)", "towncrier", "tox", "types-ujson", "uvicorn (<0.15.0)"]
-docs = ["autodocsumm (>=0.2.11)", "docutils", "enum-tools[sphinx]", "m2r2", "mistune (<2.0.0)", "pygments", "sphinx (>=2.1.2)", "sphinx-rtd-theme (>=0.4.3)"]
-ext = ["sanic-ext"]
-http3 = ["aioquic"]
-test = ["bandit", "beautifulsoup4", "chardet (==3.*)", "coverage", "docutils", "mypy", "pygments", "pytest (==7.1.*)", "pytest-benchmark", "pytest-sanic", "ruff", "sanic-testing (>=23.6.0)", "slotscheck (>=0.8.0,<1)", "types-ujson", "uvicorn (<0.15.0)"]
-
-[[package]]
-name = "sanic-beskar"
-version = "2.3.2"
-description = "Strong, Simple, (now async!) and Precise security for Sanic APIs"
-optional = false
-python-versions = ">=3.8,<3.13"
-files = [
- {file = "sanic_beskar-2.3.2-py3-none-any.whl", hash = "sha256:745c4c74b49fa3ac142a1bd31f88b2918aff710a655da677e912ce056e4697c5"},
- {file = "sanic_beskar-2.3.2.tar.gz", hash = "sha256:1266fec8523ddddb98ed46a8eab374d6e86ccd0795d2c86530c195a3afcd598b"},
-]
-
-[package.dependencies]
-cryptography = ">=39.0.0,<42.0"
-jinja2 = ">=3.1.2"
-passlib = ">=1.7"
-pendulum = [
- {version = ">=2.1,<=3.1", markers = "python_version >= \"3.8\" and python_version < \"3.12\""},
- {version = "==3.0.*", markers = "python_version >= \"3.12\""},
-]
-py-buzz = ">3.2.0,<5.0"
-pyjwt = ">=2.6"
-pyseto = ">=1.6.9"
-sanic = ">=22.6.0,<=24.0"
-
-[[package]]
-name = "sanic-ext"
-version = "23.12.0"
-description = "Extend your Sanic installation with some core functionality."
-optional = false
-python-versions = "*"
-files = [
- {file = "sanic-ext-23.12.0.tar.gz", hash = "sha256:42fc41e7fafa58f3b790f685f3dd8a8de281460b4169d0e91f4e11b8747f845c"},
- {file = "sanic_ext-23.12.0-py3-none-any.whl", hash = "sha256:3ba2c143d7c41d89b87a11c6214b9d9b52c3994ff8ce3a03792b54ec5627e2c3"},
-]
-
-[package.dependencies]
-pyyaml = ">=3.0.0"
-
-[package.extras]
-dev = ["Jinja2", "black (>=21.4b2)", "coverage", "flake8 (>=3.7.7)", "isort (>=5.0.0)", "pytest", "pytest-asyncio", "pytest-cov", "sanic-testing (>=22.9.0)", "tox"]
-test = ["Jinja2", "coverage", "pytest", "pytest-asyncio", "pytest-cov", "sanic-testing (>=22.9.0)", "tox"]
-
-[[package]]
-name = "sanic-limiter"
-version = "0.1.4"
-description = "Provides rate limiting features for Sanic. Supports in-memory, redis and memcache as storage."
-optional = false
-python-versions = "*"
-files = []
-develop = false
-
-[package.dependencies]
-limits = ">=1.2.1"
-sanic = ">=0.4.0"
-six = ">=1.4.1"
-
-[package.source]
-type = "git"
-url = "https://github.com/Omegastick/sanic-limiter"
-reference = "HEAD"
-resolved_reference = "843e13144aa21d843ce212a7c1db31b72ce8a103"
-
-[[package]]
-name = "sanic-routing"
-version = "23.12.0"
-description = "Core routing component for Sanic"
-optional = false
-python-versions = "*"
-files = [
- {file = "sanic-routing-23.12.0.tar.gz", hash = "sha256:1dcadc62c443e48c852392dba03603f9862b6197fc4cba5bbefeb1ace0848b04"},
- {file = "sanic_routing-23.12.0-py3-none-any.whl", hash = "sha256:1558a72afcb9046ed3134a5edae02fc1552cff08f0fff2e8d5de0877ea43ed73"},
-]
-
-[[package]]
-name = "sentry-sdk"
-version = "1.39.2"
-description = "Python client for Sentry (https://sentry.io)"
-optional = false
-python-versions = "*"
-files = [
- {file = "sentry-sdk-1.39.2.tar.gz", hash = "sha256:24c83b0b41c887d33328a9166f5950dc37ad58f01c9f2fbff6b87a6f1094170c"},
- {file = "sentry_sdk-1.39.2-py2.py3-none-any.whl", hash = "sha256:acaf597b30258fc7663063b291aa99e58f3096e91fe1e6634f4b79f9c1943e8e"},
-]
-
-[package.dependencies]
-certifi = "*"
-sanic = {version = ">=0.8", optional = true, markers = "extra == \"sanic\""}
-urllib3 = {version = ">=1.26.11", markers = "python_version >= \"3.6\""}
-
-[package.extras]
-aiohttp = ["aiohttp (>=3.5)"]
-arq = ["arq (>=0.23)"]
-asyncpg = ["asyncpg (>=0.23)"]
-beam = ["apache-beam (>=2.12)"]
-bottle = ["bottle (>=0.12.13)"]
-celery = ["celery (>=3)"]
-chalice = ["chalice (>=1.16.0)"]
-clickhouse-driver = ["clickhouse-driver (>=0.2.0)"]
-django = ["django (>=1.8)"]
-falcon = ["falcon (>=1.4)"]
-fastapi = ["fastapi (>=0.79.0)"]
-flask = ["blinker (>=1.1)", "flask (>=0.11)", "markupsafe"]
-grpcio = ["grpcio (>=1.21.1)"]
-httpx = ["httpx (>=0.16.0)"]
-huey = ["huey (>=2)"]
-loguru = ["loguru (>=0.5)"]
-opentelemetry = ["opentelemetry-distro (>=0.35b0)"]
-opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"]
-pure-eval = ["asttokens", "executing", "pure_eval"]
-pymongo = ["pymongo (>=3.1)"]
-pyspark = ["pyspark (>=2.4.4)"]
-quart = ["blinker (>=1.1)", "quart (>=0.16.1)"]
-rq = ["rq (>=0.6)"]
-sanic = ["sanic (>=0.8)"]
-sqlalchemy = ["sqlalchemy (>=1.2)"]
-starlette = ["starlette (>=0.19.1)"]
-starlite = ["starlite (>=1.48)"]
-tornado = ["tornado (>=5)"]
-
-[[package]]
-name = "six"
-version = "1.16.0"
-description = "Python 2 and 3 compatibility utilities"
-optional = false
-python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
-files = [
- {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
- {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
-]
-
-[[package]]
-name = "soupsieve"
-version = "2.5"
-description = "A modern CSS selector implementation for Beautiful Soup."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"},
- {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"},
-]
-
-[[package]]
-name = "sqlalchemy"
-version = "2.0.25"
-description = "Database Abstraction Library"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-win32.whl", hash = "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669"},
- {file = "SQLAlchemy-2.0.25-cp310-cp310-win_amd64.whl", hash = "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-win32.whl", hash = "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c"},
- {file = "SQLAlchemy-2.0.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-win32.whl", hash = "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2"},
- {file = "SQLAlchemy-2.0.25-cp312-cp312-win_amd64.whl", hash = "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-win32.whl", hash = "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4"},
- {file = "SQLAlchemy-2.0.25-cp37-cp37m-win_amd64.whl", hash = "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-win32.whl", hash = "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e"},
- {file = "SQLAlchemy-2.0.25-cp38-cp38-win_amd64.whl", hash = "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-win32.whl", hash = "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24"},
- {file = "SQLAlchemy-2.0.25-cp39-cp39-win_amd64.whl", hash = "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7"},
- {file = "SQLAlchemy-2.0.25-py3-none-any.whl", hash = "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3"},
- {file = "SQLAlchemy-2.0.25.tar.gz", hash = "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08"},
-]
-
-[package.dependencies]
-greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""}
-typing-extensions = ">=4.6.0"
-
-[package.extras]
-aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"]
-aioodbc = ["aioodbc", "greenlet (!=0.4.17)"]
-aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"]
-asyncio = ["greenlet (!=0.4.17)"]
-asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"]
-mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"]
-mssql = ["pyodbc"]
-mssql-pymssql = ["pymssql"]
-mssql-pyodbc = ["pyodbc"]
-mypy = ["mypy (>=0.910)"]
-mysql = ["mysqlclient (>=1.4.0)"]
-mysql-connector = ["mysql-connector-python"]
-oracle = ["cx_oracle (>=8)"]
-oracle-oracledb = ["oracledb (>=1.0.1)"]
-postgresql = ["psycopg2 (>=2.7)"]
-postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"]
-postgresql-pg8000 = ["pg8000 (>=1.29.1)"]
-postgresql-psycopg = ["psycopg (>=3.0.7)"]
-postgresql-psycopg2binary = ["psycopg2-binary"]
-postgresql-psycopg2cffi = ["psycopg2cffi"]
-postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"]
-pymysql = ["pymysql"]
-sqlcipher = ["sqlcipher3_binary"]
-
-[[package]]
-name = "toolz"
-version = "0.12.0"
-description = "List processing tools and functional utilities"
-optional = false
-python-versions = ">=3.5"
-files = [
- {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"},
- {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"},
-]
-
-[[package]]
-name = "tracerite"
-version = "1.1.1"
-description = "Human-readable HTML tracebacks for Python exceptions"
-optional = false
-python-versions = "*"
-files = [
- {file = "tracerite-1.1.1-py3-none-any.whl", hash = "sha256:3a787a9ecb1a136ea9ce17e6328e414ec414a4f644130af4e1e330bec2dece29"},
- {file = "tracerite-1.1.1.tar.gz", hash = "sha256:6400a35a187747189e4bb8d4a8e471bd86d14dbdcc94bcad23f4eda023f41356"},
-]
-
-[package.dependencies]
-html5tagger = ">=1.2.1"
-
-[[package]]
-name = "types-aiofiles"
-version = "23.2.0.20240106"
-description = "Typing stubs for aiofiles"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "types-aiofiles-23.2.0.20240106.tar.gz", hash = "sha256:ef4fa3072441c58beaadbd0d07ba18e89beff49c71648dd223e2ca861f3dac53"},
- {file = "types_aiofiles-23.2.0.20240106-py3-none-any.whl", hash = "sha256:7324f9a9f7200c1f4986a9e40a42b548290f707b967709f30b280e99fdacbd99"},
-]
-
-[[package]]
-name = "types-beautifulsoup4"
-version = "4.12.0.20240106"
-description = "Typing stubs for beautifulsoup4"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "types-beautifulsoup4-4.12.0.20240106.tar.gz", hash = "sha256:98d628985b71b140bd3bc22a8cb0ab603c2f2d08f20d37925965eb4a21739be8"},
- {file = "types_beautifulsoup4-4.12.0.20240106-py3-none-any.whl", hash = "sha256:cbdd60ab8aeac737ac014431b6e921b43e84279c0405fdd25a6900bb0e71da5b"},
-]
-
-[package.dependencies]
-types-html5lib = "*"
-
-[[package]]
-name = "types-html5lib"
-version = "1.1.11.20240106"
-description = "Typing stubs for html5lib"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "types-html5lib-1.1.11.20240106.tar.gz", hash = "sha256:fc3a1b18eb601b3eeaf92c900bd67675c0a4fa1dd1d2a2893ebdb46923547ee9"},
- {file = "types_html5lib-1.1.11.20240106-py3-none-any.whl", hash = "sha256:61993cb89220107481e0f1da65c388ff8cf3d8c5f6e8483c97559639a596b697"},
-]
-
-[[package]]
-name = "types-ujson"
-version = "5.9.0.0"
-description = "Typing stubs for ujson"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "types-ujson-5.9.0.0.tar.gz", hash = "sha256:7e7042454dc7cd7f31b09c420d7caf36b93d30bdf4b8db93791bd0561713d017"},
- {file = "types_ujson-5.9.0.0-py3-none-any.whl", hash = "sha256:f274fa604ed6317effcd1c424ef4cf292c3b0689cb118fb3180689d40ed1f4ed"},
-]
-
-[[package]]
-name = "typing-extensions"
-version = "4.9.0"
-description = "Backported and Experimental Type Hints for Python 3.8+"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"},
- {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"},
-]
-
-[[package]]
-name = "tzdata"
-version = "2023.4"
-description = "Provider of IANA time zone data"
-optional = false
-python-versions = ">=2"
-files = [
- {file = "tzdata-2023.4-py2.py3-none-any.whl", hash = "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3"},
- {file = "tzdata-2023.4.tar.gz", hash = "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9"},
-]
-
-[[package]]
-name = "ujson"
-version = "5.9.0"
-description = "Ultra fast JSON encoder and decoder for Python"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "ujson-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ab71bf27b002eaf7d047c54a68e60230fbd5cd9da60de7ca0aa87d0bccead8fa"},
- {file = "ujson-5.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7a365eac66f5aa7a7fdf57e5066ada6226700884fc7dce2ba5483538bc16c8c5"},
- {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e015122b337858dba5a3dc3533af2a8fc0410ee9e2374092f6a5b88b182e9fcc"},
- {file = "ujson-5.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:779a2a88c53039bebfbccca934430dabb5c62cc179e09a9c27a322023f363e0d"},
- {file = "ujson-5.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10ca3c41e80509fd9805f7c149068fa8dbee18872bbdc03d7cca928926a358d5"},
- {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a566e465cb2fcfdf040c2447b7dd9718799d0d90134b37a20dff1e27c0e9096"},
- {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f833c529e922577226a05bc25b6a8b3eb6c4fb155b72dd88d33de99d53113124"},
- {file = "ujson-5.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b68a0caab33f359b4cbbc10065c88e3758c9f73a11a65a91f024b2e7a1257106"},
- {file = "ujson-5.9.0-cp310-cp310-win32.whl", hash = "sha256:7cc7e605d2aa6ae6b7321c3ae250d2e050f06082e71ab1a4200b4ae64d25863c"},
- {file = "ujson-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:a6d3f10eb8ccba4316a6b5465b705ed70a06011c6f82418b59278fbc919bef6f"},
- {file = "ujson-5.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b23bbb46334ce51ddb5dded60c662fbf7bb74a37b8f87221c5b0fec1ec6454b"},
- {file = "ujson-5.9.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6974b3a7c17bbf829e6c3bfdc5823c67922e44ff169851a755eab79a3dd31ec0"},
- {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5964ea916edfe24af1f4cc68488448fbb1ec27a3ddcddc2b236da575c12c8ae"},
- {file = "ujson-5.9.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ba7cac47dd65ff88571eceeff48bf30ed5eb9c67b34b88cb22869b7aa19600d"},
- {file = "ujson-5.9.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bbd91a151a8f3358c29355a491e915eb203f607267a25e6ab10531b3b157c5e"},
- {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:829a69d451a49c0de14a9fecb2a2d544a9b2c884c2b542adb243b683a6f15908"},
- {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a807ae73c46ad5db161a7e883eec0fbe1bebc6a54890152ccc63072c4884823b"},
- {file = "ujson-5.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8fc2aa18b13d97b3c8ccecdf1a3c405f411a6e96adeee94233058c44ff92617d"},
- {file = "ujson-5.9.0-cp311-cp311-win32.whl", hash = "sha256:70e06849dfeb2548be48fdd3ceb53300640bc8100c379d6e19d78045e9c26120"},
- {file = "ujson-5.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:7309d063cd392811acc49b5016728a5e1b46ab9907d321ebbe1c2156bc3c0b99"},
- {file = "ujson-5.9.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:20509a8c9f775b3a511e308bbe0b72897ba6b800767a7c90c5cca59d20d7c42c"},
- {file = "ujson-5.9.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b28407cfe315bd1b34f1ebe65d3bd735d6b36d409b334100be8cdffae2177b2f"},
- {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d302bd17989b6bd90d49bade66943c78f9e3670407dbc53ebcf61271cadc399"},
- {file = "ujson-5.9.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f21315f51e0db8ee245e33a649dd2d9dce0594522de6f278d62f15f998e050e"},
- {file = "ujson-5.9.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5635b78b636a54a86fdbf6f027e461aa6c6b948363bdf8d4fbb56a42b7388320"},
- {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82b5a56609f1235d72835ee109163c7041b30920d70fe7dac9176c64df87c164"},
- {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5ca35f484622fd208f55041b042d9d94f3b2c9c5add4e9af5ee9946d2d30db01"},
- {file = "ujson-5.9.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:829b824953ebad76d46e4ae709e940bb229e8999e40881338b3cc94c771b876c"},
- {file = "ujson-5.9.0-cp312-cp312-win32.whl", hash = "sha256:25fa46e4ff0a2deecbcf7100af3a5d70090b461906f2299506485ff31d9ec437"},
- {file = "ujson-5.9.0-cp312-cp312-win_amd64.whl", hash = "sha256:60718f1720a61560618eff3b56fd517d107518d3c0160ca7a5a66ac949c6cf1c"},
- {file = "ujson-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d581db9db9e41d8ea0b2705c90518ba623cbdc74f8d644d7eb0d107be0d85d9c"},
- {file = "ujson-5.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ff741a5b4be2d08fceaab681c9d4bc89abf3c9db600ab435e20b9b6d4dfef12e"},
- {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cdcb02cabcb1e44381221840a7af04433c1dc3297af76fde924a50c3054c708c"},
- {file = "ujson-5.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e208d3bf02c6963e6ef7324dadf1d73239fb7008491fdf523208f60be6437402"},
- {file = "ujson-5.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f4b3917296630a075e04d3d07601ce2a176479c23af838b6cf90a2d6b39b0d95"},
- {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0c4d6adb2c7bb9eb7c71ad6f6f612e13b264942e841f8cc3314a21a289a76c4e"},
- {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:0b159efece9ab5c01f70b9d10bbb77241ce111a45bc8d21a44c219a2aec8ddfd"},
- {file = "ujson-5.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0cb4a7814940ddd6619bdce6be637a4b37a8c4760de9373bac54bb7b229698b"},
- {file = "ujson-5.9.0-cp38-cp38-win32.whl", hash = "sha256:dc80f0f5abf33bd7099f7ac94ab1206730a3c0a2d17549911ed2cb6b7aa36d2d"},
- {file = "ujson-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:506a45e5fcbb2d46f1a51fead991c39529fc3737c0f5d47c9b4a1d762578fc30"},
- {file = "ujson-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d0fd2eba664a22447102062814bd13e63c6130540222c0aa620701dd01f4be81"},
- {file = "ujson-5.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:bdf7fc21a03bafe4ba208dafa84ae38e04e5d36c0e1c746726edf5392e9f9f36"},
- {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e2f909bc08ce01f122fd9c24bc6f9876aa087188dfaf3c4116fe6e4daf7e194f"},
- {file = "ujson-5.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd4ea86c2afd41429751d22a3ccd03311c067bd6aeee2d054f83f97e41e11d8f"},
- {file = "ujson-5.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:63fb2e6599d96fdffdb553af0ed3f76b85fda63281063f1cb5b1141a6fcd0617"},
- {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:32bba5870c8fa2a97f4a68f6401038d3f1922e66c34280d710af00b14a3ca562"},
- {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:37ef92e42535a81bf72179d0e252c9af42a4ed966dc6be6967ebfb929a87bc60"},
- {file = "ujson-5.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f69f16b8f1c69da00e38dc5f2d08a86b0e781d0ad3e4cc6a13ea033a439c4844"},
- {file = "ujson-5.9.0-cp39-cp39-win32.whl", hash = "sha256:3382a3ce0ccc0558b1c1668950008cece9bf463ebb17463ebf6a8bfc060dae34"},
- {file = "ujson-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:6adef377ed583477cf005b58c3025051b5faa6b8cc25876e594afbb772578f21"},
- {file = "ujson-5.9.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ffdfebd819f492e48e4f31c97cb593b9c1a8251933d8f8972e81697f00326ff1"},
- {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4eec2ddc046360d087cf35659c7ba0cbd101f32035e19047013162274e71fcf"},
- {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbb90aa5c23cb3d4b803c12aa220d26778c31b6e4b7a13a1f49971f6c7d088e"},
- {file = "ujson-5.9.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0823cb70866f0d6a4ad48d998dd338dce7314598721bc1b7986d054d782dfd"},
- {file = "ujson-5.9.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4e35d7885ed612feb6b3dd1b7de28e89baaba4011ecdf995e88be9ac614765e9"},
- {file = "ujson-5.9.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b048aa93eace8571eedbd67b3766623e7f0acbf08ee291bef7d8106210432427"},
- {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:323279e68c195110ef85cbe5edce885219e3d4a48705448720ad925d88c9f851"},
- {file = "ujson-5.9.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ac92d86ff34296f881e12aa955f7014d276895e0e4e868ba7fddebbde38e378"},
- {file = "ujson-5.9.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6eecbd09b316cea1fd929b1e25f70382917542ab11b692cb46ec9b0a26c7427f"},
- {file = "ujson-5.9.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:473fb8dff1d58f49912323d7cb0859df5585cfc932e4b9c053bf8cf7f2d7c5c4"},
- {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f91719c6abafe429c1a144cfe27883eace9fb1c09a9c5ef1bcb3ae80a3076a4e"},
- {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1c0991c4fe256f5fdb19758f7eac7f47caac29a6c57d0de16a19048eb86bad"},
- {file = "ujson-5.9.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a8ea0f55a1396708e564595aaa6696c0d8af532340f477162ff6927ecc46e21"},
- {file = "ujson-5.9.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:07e0cfdde5fd91f54cd2d7ffb3482c8ff1bf558abf32a8b953a5d169575ae1cd"},
- {file = "ujson-5.9.0.tar.gz", hash = "sha256:89cc92e73d5501b8a7f48575eeb14ad27156ad092c2e9fc7e3cf949f07e75532"},
-]
-
-[[package]]
-name = "urllib3"
-version = "2.1.0"
-description = "HTTP library with thread-safe connection pooling, file post, and more."
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "urllib3-2.1.0-py3-none-any.whl", hash = "sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3"},
- {file = "urllib3-2.1.0.tar.gz", hash = "sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54"},
-]
-
-[package.extras]
-brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
-socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
-zstd = ["zstandard (>=0.18.0)"]
-
-[[package]]
-name = "uvloop"
-version = "0.19.0"
-description = "Fast implementation of asyncio event loop on top of libuv"
-optional = false
-python-versions = ">=3.8.0"
-files = [
- {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de4313d7f575474c8f5a12e163f6d89c0a878bc49219641d49e6f1444369a90e"},
- {file = "uvloop-0.19.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5588bd21cf1fcf06bded085f37e43ce0e00424197e7c10e77afd4bbefffef428"},
- {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b1fd71c3843327f3bbc3237bedcdb6504fd50368ab3e04d0410e52ec293f5b8"},
- {file = "uvloop-0.19.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a05128d315e2912791de6088c34136bfcdd0c7cbc1cf85fd6fd1bb321b7c849"},
- {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:cd81bdc2b8219cb4b2556eea39d2e36bfa375a2dd021404f90a62e44efaaf957"},
- {file = "uvloop-0.19.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5f17766fb6da94135526273080f3455a112f82570b2ee5daa64d682387fe0dcd"},
- {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4ce6b0af8f2729a02a5d1575feacb2a94fc7b2e983868b009d51c9a9d2149bef"},
- {file = "uvloop-0.19.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:31e672bb38b45abc4f26e273be83b72a0d28d074d5b370fc4dcf4c4eb15417d2"},
- {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:570fc0ed613883d8d30ee40397b79207eedd2624891692471808a95069a007c1"},
- {file = "uvloop-0.19.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5138821e40b0c3e6c9478643b4660bd44372ae1e16a322b8fc07478f92684e24"},
- {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:91ab01c6cd00e39cde50173ba4ec68a1e578fee9279ba64f5221810a9e786533"},
- {file = "uvloop-0.19.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:47bf3e9312f63684efe283f7342afb414eea4d3011542155c7e625cd799c3b12"},
- {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:da8435a3bd498419ee8c13c34b89b5005130a476bda1d6ca8cfdde3de35cd650"},
- {file = "uvloop-0.19.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:02506dc23a5d90e04d4f65c7791e65cf44bd91b37f24cfc3ef6cf2aff05dc7ec"},
- {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2693049be9d36fef81741fddb3f441673ba12a34a704e7b4361efb75cf30befc"},
- {file = "uvloop-0.19.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7010271303961c6f0fe37731004335401eb9075a12680738731e9c92ddd96ad6"},
- {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:5daa304d2161d2918fa9a17d5635099a2f78ae5b5960e742b2fcfbb7aefaa593"},
- {file = "uvloop-0.19.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:7207272c9520203fea9b93843bb775d03e1cf88a80a936ce760f60bb5add92f3"},
- {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:78ab247f0b5671cc887c31d33f9b3abfb88d2614b84e4303f1a63b46c046c8bd"},
- {file = "uvloop-0.19.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:472d61143059c84947aa8bb74eabbace30d577a03a1805b77933d6bd13ddebbd"},
- {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45bf4c24c19fb8a50902ae37c5de50da81de4922af65baf760f7c0c42e1088be"},
- {file = "uvloop-0.19.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:271718e26b3e17906b28b67314c45d19106112067205119dddbd834c2b7ce797"},
- {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:34175c9fd2a4bc3adc1380e1261f60306344e3407c20a4d684fd5f3be010fa3d"},
- {file = "uvloop-0.19.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7"},
- {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:13dfdf492af0aa0a0edf66807d2b465607d11c4fa48f4a1fd41cbea5b18e8e8b"},
- {file = "uvloop-0.19.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6e3d4e85ac060e2342ff85e90d0c04157acb210b9ce508e784a944f852a40e67"},
- {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8ca4956c9ab567d87d59d49fa3704cf29e37109ad348f2d5223c9bf761a332e7"},
- {file = "uvloop-0.19.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256"},
- {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:492e2c32c2af3f971473bc22f086513cedfc66a130756145a931a90c3958cb17"},
- {file = "uvloop-0.19.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2df95fca285a9f5bfe730e51945ffe2fa71ccbfdde3b0da5772b4ee4f2e770d5"},
- {file = "uvloop-0.19.0.tar.gz", hash = "sha256:0246f4fd1bf2bf702e06b0d45ee91677ee5c31242f39aab4ea6fe0c51aedd0fd"},
-]
-
-[package.extras]
-docs = ["Sphinx (>=4.1.2,<4.2.0)", "sphinx-rtd-theme (>=0.5.2,<0.6.0)", "sphinxcontrib-asyncio (>=0.3.0,<0.4.0)"]
-test = ["Cython (>=0.29.36,<0.30.0)", "aiohttp (==3.9.0b0)", "aiohttp (>=3.8.1)", "flake8 (>=5.0,<6.0)", "mypy (>=0.800)", "psutil", "pyOpenSSL (>=23.0.0,<23.1.0)", "pycodestyle (>=2.9.0,<2.10.0)"]
-
-[[package]]
-name = "websockets"
-version = "12.0"
-description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
-optional = false
-python-versions = ">=3.8"
-files = [
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374"},
- {file = "websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be"},
- {file = "websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558"},
- {file = "websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8"},
- {file = "websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603"},
- {file = "websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f"},
- {file = "websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4"},
- {file = "websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f"},
- {file = "websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45"},
- {file = "websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca"},
- {file = "websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53"},
- {file = "websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402"},
- {file = "websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df"},
- {file = "websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc"},
- {file = "websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92"},
- {file = "websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2"},
- {file = "websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113"},
- {file = "websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d"},
- {file = "websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5f6ffe2c6598f7f7207eef9a1228b6f5c818f9f4d53ee920aacd35cec8110438"},
- {file = "websockets-12.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9edf3fc590cc2ec20dc9d7a45108b5bbaf21c0d89f9fd3fd1685e223771dc0b2"},
- {file = "websockets-12.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8572132c7be52632201a35f5e08348137f658e5ffd21f51f94572ca6c05ea81d"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:604428d1b87edbf02b233e2c207d7d528460fa978f9e391bd8aaf9c8311de137"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a9d160fd080c6285e202327aba140fc9a0d910b09e423afff4ae5cbbf1c7205"},
- {file = "websockets-12.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b4aafed34653e465eb77b7c93ef058516cb5acf3eb21e42f33928616172def"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b2ee7288b85959797970114deae81ab41b731f19ebcd3bd499ae9ca0e3f1d2c8"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:7fa3d25e81bfe6a89718e9791128398a50dec6d57faf23770787ff441d851967"},
- {file = "websockets-12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a571f035a47212288e3b3519944f6bf4ac7bc7553243e41eac50dd48552b6df7"},
- {file = "websockets-12.0-cp38-cp38-win32.whl", hash = "sha256:3c6cc1360c10c17463aadd29dd3af332d4a1adaa8796f6b0e9f9df1fdb0bad62"},
- {file = "websockets-12.0-cp38-cp38-win_amd64.whl", hash = "sha256:1bf386089178ea69d720f8db6199a0504a406209a0fc23e603b27b300fdd6892"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d"},
- {file = "websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28"},
- {file = "websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec"},
- {file = "websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b"},
- {file = "websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9"},
- {file = "websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6"},
- {file = "websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8"},
- {file = "websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077"},
- {file = "websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b"},
- {file = "websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30"},
- {file = "websockets-12.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:0bee75f400895aef54157b36ed6d3b308fcab62e5260703add87f44cee9c82a6"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:423fc1ed29f7512fceb727e2d2aecb952c46aa34895e9ed96071821309951123"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27a5e9964ef509016759f2ef3f2c1e13f403725a5e6a1775555994966a66e931"},
- {file = "websockets-12.0-pp38-pypy38_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c3181df4583c4d3994d31fb235dc681d2aaad744fbdbf94c4802485ececdecf2"},
- {file = "websockets-12.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:b067cb952ce8bf40115f6c19f478dc71c5e719b7fbaa511359795dfd9d1a6468"},
- {file = "websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7"},
- {file = "websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611"},
- {file = "websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370"},
- {file = "websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e"},
- {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"},
-]
-
-[[package]]
-name = "wrapt"
-version = "1.16.0"
-description = "Module for decorators, wrappers and monkey patching."
-optional = false
-python-versions = ">=3.6"
-files = [
- {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"},
- {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"},
- {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"},
- {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"},
- {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"},
- {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"},
- {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"},
- {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"},
- {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"},
- {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"},
- {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"},
- {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"},
- {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"},
- {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"},
- {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"},
- {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"},
- {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"},
- {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"},
- {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"},
- {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"},
- {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"},
- {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"},
- {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"},
- {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"},
- {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"},
- {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"},
- {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"},
- {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"},
- {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"},
- {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"},
- {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"},
- {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"},
- {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"},
- {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"},
- {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"},
- {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"},
- {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"},
- {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"},
- {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"},
- {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"},
- {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"},
- {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"},
- {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"},
- {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"},
- {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"},
- {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"},
- {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"},
- {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"},
- {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"},
- {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"},
- {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"},
- {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"},
- {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"},
- {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"},
- {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"},
- {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"},
- {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"},
- {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"},
- {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"},
- {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"},
- {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"},
- {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"},
- {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"},
- {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"},
- {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"},
- {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"},
- {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"},
- {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"},
- {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"},
- {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"},
-]
-
-[[package]]
-name = "yarl"
-version = "1.9.4"
-description = "Yet another URL library"
-optional = false
-python-versions = ">=3.7"
-files = [
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"},
- {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"},
- {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"},
- {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"},
- {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"},
- {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"},
- {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"},
- {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"},
- {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"},
- {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"},
- {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"},
- {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"},
- {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"},
- {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"},
- {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"},
- {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"},
- {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"},
- {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"},
- {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"},
- {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"},
- {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"},
- {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"},
- {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"},
- {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"},
- {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"},
- {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"},
- {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"},
- {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"},
- {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"},
- {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"},
- {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"},
- {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"},
- {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"},
-]
-
-[package.dependencies]
-idna = ">=2.0"
-multidict = ">=4.0"
-
-[metadata]
-lock-version = "2.0"
-python-versions = ">=3.11,<3.13"
-content-hash = "adb47607ce6269e06fd1e7ef3b34f6f66df3dbc730d4609980a97a4e60977add"
diff --git a/pyproject.toml b/pyproject.toml
deleted file mode 100644
index 2ea4099f..00000000
--- a/pyproject.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[tool.poetry]
-name = "revanced-api"
-version = "0.1.0"
-description = ""
-authors = ["Alexandre Teles "]
-license = "AGPLv3"
-readme = "README.md"
-
-[tool.poetry.dependencies]
-python = ">=3.11,<3.13"
-aiohttp = { version = "^3.9.1", extras = ["speedups"] }
-sanic = { version = "^23.12.1", extras = ["ext"] }
-ujson = "^5.9.0"
-pydantic = "^1.10.13"
-asyncstdlib = "^3.12.0"
-cytoolz = "^0.12.2"
-beautifulsoup4 = "^4.12.2"
-lxml = "^5.1.0"
-sqlalchemy = "^2.0.25"
-sanic-beskar = "^2.3.2"
-bson = "^0.5.10"
-fastpbkdf2 = "^0.2"
-cryptography = "^41.0.7"
-sanic-limiter = { git = "https://github.com/Omegastick/sanic-limiter" }
-sentry-sdk = { extras = ["sanic"], version = "^1.39.2" }
-
-[tool.poetry.dev-dependencies]
-mypy = "^1.8.0"
-types-ujson = "^5.9.0.0"
-types-aiofiles = "^23.2.0.20240106"
-types-beautifulsoup4 = "^4.12.0.20240106"
-
-[tool.pytest.ini_options]
-asyncio_mode = "auto"
-filterwarnings = [
- "ignore::DeprecationWarning",
- "ignore::pytest.PytestCollectionWarning",
-]
-
-[build-system]
-requires = ["poetry-core"]
-build-backend = "poetry.core.masonry.api"
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index c93aedb5..00000000
--- a/requirements.txt
+++ /dev/null
@@ -1,62 +0,0 @@
-aiodns==3.1.1 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "3.13"
-aiofiles==23.2.1 ; python_version >= "3.11" and python_version < "3.13"
-aiohttp[speedups]==3.9.1 ; python_version >= "3.11" and python_version < "3.13"
-aiosignal==1.3.1 ; python_version >= "3.11" and python_version < "3.13"
-argon2-cffi-bindings==21.2.0 ; python_version >= "3.11" and python_version < "3.13"
-argon2-cffi==23.1.0 ; python_version >= "3.11" and python_version < "3.13"
-asyncstdlib==3.12.0 ; python_version >= "3.11" and python_version < "3.13"
-attrs==23.2.0 ; python_version >= "3.11" and python_version < "3.13"
-beautifulsoup4==4.12.2 ; python_version >= "3.11" and python_version < "3.13"
-brotli==1.1.0 ; platform_python_implementation == "CPython" and python_version >= "3.11" and python_version < "3.13"
-brotlicffi==1.1.0.0 ; platform_python_implementation != "CPython" and python_version >= "3.11" and python_version < "3.13"
-bson==0.5.10 ; python_version >= "3.11" and python_version < "3.13"
-certifi==2023.11.17 ; python_version >= "3.11" and python_version < "3.13"
-cffi==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
-cryptography==41.0.7 ; python_version >= "3.11" and python_version < "3.13"
-cytoolz==0.12.2 ; python_version >= "3.11" and python_version < "3.13"
-deprecated==1.2.14 ; python_version >= "3.11" and python_version < "3.13"
-fastpbkdf2==0.2 ; python_version >= "3.11" and python_version < "3.13"
-frozenlist==1.4.1 ; python_version >= "3.11" and python_version < "3.13"
-greenlet==3.0.3 ; python_version >= "3.11" and python_version < "3.13" and (platform_machine == "aarch64" or platform_machine == "ppc64le" or platform_machine == "x86_64" or platform_machine == "amd64" or platform_machine == "AMD64" or platform_machine == "win32" or platform_machine == "WIN32")
-html5tagger==1.3.0 ; python_version >= "3.11" and python_version < "3.13"
-httptools==0.6.1 ; python_version >= "3.11" and python_version < "3.13"
-idna==3.6 ; python_version >= "3.11" and python_version < "3.13"
-importlib-resources==6.1.1 ; python_version >= "3.11" and python_version < "3.13"
-iso8601==2.1.0 ; python_version >= "3.11" and python_version < "3.13"
-jinja2==3.1.3 ; python_version >= "3.11" and python_version < "3.13"
-limits==3.7.0 ; python_version >= "3.11" and python_version < "3.13"
-lxml==5.1.0 ; python_version >= "3.11" and python_version < "3.13"
-markupsafe==2.1.3 ; python_version >= "3.11" and python_version < "3.13"
-multidict==6.0.4 ; python_version >= "3.11" and python_version < "3.13"
-packaging==23.2 ; python_version >= "3.11" and python_version < "3.13"
-passlib==1.7.4 ; python_version >= "3.11" and python_version < "3.13"
-pendulum==3.0.0 ; python_version >= "3.11" and python_version < "3.13"
-py-buzz==4.1.0 ; python_version >= "3.11" and python_version < "3.13"
-pycares==4.4.0 ; (sys_platform == "linux" or sys_platform == "darwin") and python_version >= "3.11" and python_version < "3.13"
-pycparser==2.21 ; python_version >= "3.11" and python_version < "3.13"
-pycryptodomex==3.20.0 ; python_version >= "3.11" and python_version < "3.13"
-pydantic==1.10.13 ; python_version >= "3.11" and python_version < "3.13"
-pyjwt==2.8.0 ; python_version >= "3.11" and python_version < "3.13"
-pyseto==1.7.7 ; python_version >= "3.11" and python_version < "3.13"
-python-dateutil==2.8.2 ; python_version >= "3.11" and python_version < "3.13"
-pyyaml==6.0.1 ; python_version >= "3.11" and python_version < "3.13"
-sanic-beskar==2.3.2 ; python_version >= "3.11" and python_version < "3.13"
-sanic-ext==23.12.0 ; python_version >= "3.11" and python_version < "3.13"
-sanic-limiter @ git+https://github.com/Omegastick/sanic-limiter@843e13144aa21d843ce212a7c1db31b72ce8a103 ; python_version >= "3.11" and python_version < "3.13"
-sanic-routing==23.12.0 ; python_version >= "3.11" and python_version < "3.13"
-sanic==23.12.1 ; python_version >= "3.11" and python_version < "3.13"
-sanic[ext]==23.12.1 ; python_version >= "3.11" and python_version < "3.13"
-sentry-sdk[sanic]==1.39.2 ; python_version >= "3.11" and python_version < "3.13"
-six==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
-soupsieve==2.5 ; python_version >= "3.11" and python_version < "3.13"
-sqlalchemy==2.0.25 ; python_version >= "3.11" and python_version < "3.13"
-toolz==0.12.0 ; python_version >= "3.11" and python_version < "3.13"
-tracerite==1.1.1 ; python_version >= "3.11" and python_version < "3.13"
-typing-extensions==4.9.0 ; python_version >= "3.11" and python_version < "3.13"
-tzdata==2023.4 ; python_version >= "3.11" and python_version < "3.13"
-ujson==5.9.0 ; python_version >= "3.11" and python_version < "3.13"
-urllib3==2.1.0 ; python_version >= "3.11" and python_version < "3.13"
-uvloop==0.19.0 ; sys_platform != "win32" and implementation_name == "cpython" and python_version >= "3.11" and python_version < "3.13"
-websockets==12.0 ; python_version >= "3.11" and python_version < "3.13"
-wrapt==1.16.0 ; python_version >= "3.11" and python_version < "3.13"
-yarl==1.9.4 ; python_version >= "3.11" and python_version < "3.13"
diff --git a/settings.gradle.kts b/settings.gradle.kts
new file mode 100644
index 00000000..44d1e0df
--- /dev/null
+++ b/settings.gradle.kts
@@ -0,0 +1,7 @@
+rootProject.name = "revanced-api"
+
+buildCache {
+ local {
+ isEnabled = "CI" !in System.getenv()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/command/MainCommand.kt b/src/main/kotlin/app/revanced/api/command/MainCommand.kt
new file mode 100644
index 00000000..c665597b
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/command/MainCommand.kt
@@ -0,0 +1,34 @@
+package app.revanced.api.command
+
+import picocli.CommandLine
+import java.util.*
+
+internal val applicationVersion = MainCommand::class.java.getResourceAsStream(
+ "/app/revanced/api/version.properties",
+)?.use { stream ->
+ Properties().apply {
+ load(stream)
+ }.getProperty("version")
+} ?: "v0.0.0"
+
+fun main(args: Array) {
+ CommandLine(MainCommand).execute(*args).let(System::exit)
+}
+
+private object CLIVersionProvider : CommandLine.IVersionProvider {
+ override fun getVersion() =
+ arrayOf(
+ "ReVanced API $applicationVersion",
+ )
+}
+
+@CommandLine.Command(
+ name = "revanced-api",
+ description = ["API server for ReVanced"],
+ mixinStandardHelpOptions = true,
+ versionProvider = CLIVersionProvider::class,
+ subcommands = [
+ StartAPICommand::class,
+ ],
+)
+private object MainCommand
diff --git a/src/main/kotlin/app/revanced/api/command/StartAPICommand.kt b/src/main/kotlin/app/revanced/api/command/StartAPICommand.kt
new file mode 100644
index 00000000..370fa765
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/command/StartAPICommand.kt
@@ -0,0 +1,46 @@
+package app.revanced.api.command
+
+import app.revanced.api.configuration.*
+import io.ktor.server.engine.*
+import io.ktor.server.jetty.*
+import picocli.CommandLine
+import java.io.File
+
+@CommandLine.Command(
+ name = "start",
+ description = ["Start the API server"],
+)
+internal object StartAPICommand : Runnable {
+ @CommandLine.Option(
+ names = ["-h", "--host"],
+ description = ["The host address to bind to."],
+ showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
+ )
+ private var host: String = "0.0.0.0"
+
+ @CommandLine.Option(
+ names = ["-p", "--port"],
+ description = ["The port to listen on."],
+ showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
+ )
+ private var port: Int = 8888
+
+ @CommandLine.Option(
+ names = ["-c", "--config"],
+ description = ["The path to the configuration file."],
+ showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
+ )
+ private var configFile = File("configuration.toml")
+
+ override fun run() {
+ embeddedServer(Jetty, port, host) {
+ configureDependencies(configFile)
+ configureHTTP()
+ configureSerialization()
+ configureSecurity()
+ configureOpenAPI()
+ configureLogging()
+ configureRouting()
+ }.start(wait = true)
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Dependencies.kt b/src/main/kotlin/app/revanced/api/configuration/Dependencies.kt
new file mode 100644
index 00000000..a8ed717e
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Dependencies.kt
@@ -0,0 +1,148 @@
+package app.revanced.api.configuration
+
+import app.revanced.api.configuration.repository.AnnouncementRepository
+import app.revanced.api.configuration.repository.BackendRepository
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import app.revanced.api.configuration.repository.GitHubBackendRepository
+import app.revanced.api.configuration.services.*
+import app.revanced.api.configuration.services.AnnouncementService
+import app.revanced.api.configuration.services.ApiService
+import app.revanced.api.configuration.services.AuthService
+import app.revanced.api.configuration.services.OldApiService
+import app.revanced.api.configuration.services.PatchesService
+import com.akuleshov7.ktoml.Toml
+import com.akuleshov7.ktoml.source.decodeFromStream
+import io.github.cdimascio.dotenv.Dotenv
+import io.ktor.client.*
+import io.ktor.client.engine.okhttp.*
+import io.ktor.client.plugins.*
+import io.ktor.client.plugins.auth.*
+import io.ktor.client.plugins.auth.providers.*
+import io.ktor.client.plugins.cache.*
+import io.ktor.client.plugins.contentnegotiation.*
+import io.ktor.client.plugins.resources.*
+import io.ktor.serialization.kotlinx.json.*
+import io.ktor.server.application.*
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonNamingStrategy
+import org.jetbrains.exposed.sql.Database
+import org.jetbrains.exposed.sql.transactions.TransactionManager
+import org.koin.core.module.dsl.singleOf
+import org.koin.core.parameter.parameterArrayOf
+import org.koin.dsl.module
+import org.koin.ktor.plugin.Koin
+import java.io.File
+
+@OptIn(ExperimentalSerializationApi::class)
+fun Application.configureDependencies(
+ configFile: File,
+) {
+ val globalModule = module {
+ single {
+ Dotenv.configure().load()
+ }
+
+ factory { params ->
+ val defaultRequestUri: String = params.get()
+ val configBlock = params.getOrNull<(HttpClientConfig.() -> Unit)>() ?: {}
+
+ HttpClient(OkHttp) {
+ defaultRequest { url(defaultRequestUri) }
+
+ configBlock()
+ }
+ }
+ }
+
+ val repositoryModule = module {
+ single {
+ GitHubBackendRepository(
+ get {
+ val defaultRequestUri = "https://api.github.com"
+ val configBlock: HttpClientConfig.() -> Unit = {
+ install(HttpCache)
+ install(Resources)
+ install(ContentNegotiation) {
+ json(
+ Json {
+ ignoreUnknownKeys = true
+ namingStrategy = JsonNamingStrategy.SnakeCase
+ },
+ )
+ }
+
+ get()["BACKEND_API_TOKEN"]?.let {
+ install(Auth) {
+ bearer {
+ loadTokens {
+ BearerTokens(
+ accessToken = it,
+ refreshToken = "", // Required dummy value
+ )
+ }
+
+ sendWithoutRequest { true }
+ }
+ }
+ }
+ }
+
+ parameterArrayOf(defaultRequestUri, configBlock)
+ },
+ )
+ }
+
+ single {
+ Toml.decodeFromStream(configFile.inputStream())
+ }
+
+ single {
+ val dotenv = get()
+
+ TransactionManager.defaultDatabase = Database.connect(
+ url = dotenv["DB_URL"],
+ user = dotenv["DB_USER"],
+ password = dotenv["DB_PASSWORD"],
+ )
+
+ AnnouncementRepository()
+ }
+ }
+
+ val serviceModule = module {
+ single {
+ val dotenv = get()
+
+ val jwtSecret = dotenv["JWT_SECRET"]
+ val issuer = dotenv["JWT_ISSUER"]
+ val validityInMin = dotenv["JWT_VALIDITY_IN_MIN"].toInt()
+
+ val authSHA256DigestString = dotenv["AUTH_SHA256_DIGEST"]
+
+ AuthService(issuer, validityInMin, jwtSecret, authSHA256DigestString)
+ }
+ single {
+ val configuration = get()
+
+ OldApiService(
+ get {
+ parameterArrayOf(configuration.oldApiEndpoint)
+ },
+ )
+ }
+ singleOf(::AnnouncementService)
+ singleOf(::SignatureService)
+ singleOf(::PatchesService)
+ singleOf(::ManagerService)
+ singleOf(::ApiService)
+ }
+
+ install(Koin) {
+ modules(
+ globalModule,
+ repositoryModule,
+ serviceModule,
+ )
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Extensions.kt b/src/main/kotlin/app/revanced/api/configuration/Extensions.kt
new file mode 100644
index 00000000..d7546939
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Extensions.kt
@@ -0,0 +1,27 @@
+package app.revanced.api.configuration
+
+import io.bkbn.kompendium.core.plugin.NotarizedRoute
+import io.ktor.http.*
+import io.ktor.http.content.*
+import io.ktor.server.application.*
+import io.ktor.server.plugins.cachingheaders.*
+import io.ktor.server.response.*
+import kotlin.time.Duration
+
+internal suspend fun ApplicationCall.respondOrNotFound(value: Any?) = respond(value ?: HttpStatusCode.NotFound)
+
+internal fun ApplicationCallPipeline.installCache(maxAge: Duration) =
+ installCache(CacheControl.MaxAge(maxAgeSeconds = maxAge.inWholeSeconds.toInt()))
+
+internal fun ApplicationCallPipeline.installNoCache() =
+ installCache(CacheControl.NoCache(null))
+
+internal fun ApplicationCallPipeline.installCache(cacheControl: CacheControl) =
+ install(CachingHeaders) {
+ options { _, _ ->
+ CachingOptions(cacheControl)
+ }
+ }
+
+internal fun ApplicationCallPipeline.installNotarizedRoute(configure: NotarizedRoute.Config.() -> Unit = {}) =
+ install(NotarizedRoute(), configure)
diff --git a/src/main/kotlin/app/revanced/api/configuration/HTTP.kt b/src/main/kotlin/app/revanced/api/configuration/HTTP.kt
new file mode 100644
index 00000000..0e79530f
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/HTTP.kt
@@ -0,0 +1,40 @@
+package app.revanced.api.configuration
+
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import io.ktor.server.application.*
+import io.ktor.server.plugins.*
+import io.ktor.server.plugins.cors.routing.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.request.*
+import org.koin.ktor.ext.get
+import kotlin.time.Duration.Companion.minutes
+
+fun Application.configureHTTP() {
+ val configurationRepository = get()
+
+ install(CORS) {
+ configurationRepository.corsAllowedHosts.forEach { host ->
+ allowHost(
+ host = host,
+ schemes = listOf("http", "https")
+ )
+ }
+ }
+
+ install(RateLimit) {
+ fun rateLimit(name: String, block: RateLimitProviderConfig.() -> Unit) = register(RateLimitName(name)) {
+ requestKey {
+ it.request.uri + it.request.origin.remoteAddress
+ }
+
+ block()
+ }
+
+ rateLimit("weak") {
+ rateLimiter(limit = 30, refillPeriod = 2.minutes)
+ }
+ rateLimit("strong") {
+ rateLimiter(limit = 5, refillPeriod = 1.minutes)
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Logging.kt b/src/main/kotlin/app/revanced/api/configuration/Logging.kt
new file mode 100644
index 00000000..48b8eb7d
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Logging.kt
@@ -0,0 +1,16 @@
+package app.revanced.api.configuration
+
+import io.ktor.server.application.*
+import io.ktor.server.plugins.callloging.*
+import io.ktor.server.request.*
+
+internal fun Application.configureLogging() {
+ install(CallLogging) {
+ format { call ->
+ val status = call.response.status()
+ val httpMethod = call.request.httpMethod.value
+ val uri = call.request.uri
+ "$status $httpMethod $uri"
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/OpenAPI.kt b/src/main/kotlin/app/revanced/api/configuration/OpenAPI.kt
new file mode 100644
index 00000000..3c903215
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/OpenAPI.kt
@@ -0,0 +1,51 @@
+package app.revanced.api.configuration
+
+import app.revanced.api.command.applicationVersion
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import io.bkbn.kompendium.core.plugin.NotarizedApplication
+import io.bkbn.kompendium.json.schema.KotlinXSchemaConfigurator
+import io.bkbn.kompendium.oas.OpenApiSpec
+import io.bkbn.kompendium.oas.component.Components
+import io.bkbn.kompendium.oas.info.Contact
+import io.bkbn.kompendium.oas.info.Info
+import io.bkbn.kompendium.oas.info.License
+import io.bkbn.kompendium.oas.security.BearerAuth
+import io.bkbn.kompendium.oas.server.Server
+import io.ktor.server.application.*
+import org.koin.ktor.ext.get
+import java.net.URI
+
+internal fun Application.configureOpenAPI() {
+ val configurationRepository = get()
+
+ install(NotarizedApplication()) {
+ spec = OpenApiSpec(
+ info = Info(
+ title = "ReVanced API",
+ version = applicationVersion,
+ description = "API server for ReVanced.",
+ contact = Contact(
+ name = "ReVanced",
+ url = URI("https://revanced.app"),
+ email = "contact@revanced.app",
+ ),
+ license = License(
+ name = "AGPLv3",
+ url = URI("https://github.com/ReVanced/revanced-api/blob/main/LICENSE"),
+ ),
+ ),
+ components = Components(
+ securitySchemes = mutableMapOf(
+ "bearer" to BearerAuth(),
+ ),
+ ),
+ ).apply {
+ servers += Server(
+ url = URI(configurationRepository.endpoint),
+ description = "ReVanced API server",
+ )
+ }
+
+ schemaConfigurator = KotlinXSchemaConfigurator()
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Routing.kt b/src/main/kotlin/app/revanced/api/configuration/Routing.kt
new file mode 100644
index 00000000..fe60ebc0
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Routing.kt
@@ -0,0 +1,40 @@
+package app.revanced.api.configuration
+
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import app.revanced.api.configuration.routes.*
+import app.revanced.api.configuration.routes.announcementsRoute
+import app.revanced.api.configuration.routes.apiRoute
+import app.revanced.api.configuration.routes.oldApiRoute
+import app.revanced.api.configuration.routes.patchesRoute
+import io.bkbn.kompendium.core.routes.redoc
+import io.bkbn.kompendium.core.routes.swagger
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.http.content.*
+import io.ktor.server.routing.*
+import kotlin.time.Duration.Companion.minutes
+import org.koin.ktor.ext.get as koinGet
+
+internal fun Application.configureRouting() = routing {
+ val configuration = koinGet()
+
+ installCache(5.minutes)
+
+ route("/v${configuration.apiVersion}") {
+ announcementsRoute()
+ patchesRoute()
+ managerRoute()
+ apiRoute()
+ }
+
+ staticResources("/", "/app/revanced/api/static/root") {
+ contentType { ContentType.Application.Json }
+ extensions("json")
+ }
+
+ swagger(pageTitle = "ReVanced API", path = "/")
+ redoc(pageTitle = "ReVanced API", path = "/redoc")
+
+ // TODO: Remove, once migration period from v2 API is over (In 1-2 years).
+ oldApiRoute()
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Security.kt b/src/main/kotlin/app/revanced/api/configuration/Security.kt
new file mode 100644
index 00000000..1d6d3864
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Security.kt
@@ -0,0 +1,9 @@
+package app.revanced.api.configuration
+
+import app.revanced.api.configuration.services.AuthService
+import io.ktor.server.application.*
+import org.koin.ktor.ext.get
+
+fun Application.configureSecurity() {
+ get().configureSecurity(this)
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/Serialization.kt b/src/main/kotlin/app/revanced/api/configuration/Serialization.kt
new file mode 100644
index 00000000..1c4b939c
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/Serialization.kt
@@ -0,0 +1,23 @@
+package app.revanced.api.configuration
+
+import io.bkbn.kompendium.oas.serialization.KompendiumSerializersModule
+import io.ktor.serialization.kotlinx.json.*
+import io.ktor.server.application.*
+import io.ktor.server.plugins.contentnegotiation.*
+import kotlinx.serialization.ExperimentalSerializationApi
+import kotlinx.serialization.json.Json
+import kotlinx.serialization.json.JsonNamingStrategy
+
+@OptIn(ExperimentalSerializationApi::class)
+fun Application.configureSerialization() {
+ install(ContentNegotiation) {
+ json(
+ Json {
+ serializersModule = KompendiumSerializersModule.module
+ namingStrategy = JsonNamingStrategy.SnakeCase
+ explicitNulls = false
+ encodeDefaults = true
+ },
+ )
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/repository/AnnouncementRepository.kt b/src/main/kotlin/app/revanced/api/configuration/repository/AnnouncementRepository.kt
new file mode 100644
index 00000000..992b06ff
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/repository/AnnouncementRepository.kt
@@ -0,0 +1,191 @@
+package app.revanced.api.configuration.repository
+
+import app.revanced.api.configuration.schema.APIAnnouncement
+import app.revanced.api.configuration.schema.APIResponseAnnouncement
+import app.revanced.api.configuration.schema.APIResponseAnnouncementId
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.runBlocking
+import kotlinx.datetime.*
+import org.jetbrains.exposed.dao.IntEntity
+import org.jetbrains.exposed.dao.IntEntityClass
+import org.jetbrains.exposed.dao.id.EntityID
+import org.jetbrains.exposed.dao.id.IntIdTable
+import org.jetbrains.exposed.sql.*
+import org.jetbrains.exposed.sql.kotlin.datetime.CurrentDateTime
+import org.jetbrains.exposed.sql.kotlin.datetime.datetime
+import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
+import org.jetbrains.exposed.sql.transactions.experimental.suspendedTransactionAsync
+
+internal class AnnouncementRepository {
+ // This is better than doing a maxByOrNull { it.id }.
+ private var latestAnnouncement: Announcement? = null
+ private val latestAnnouncementByChannel = mutableMapOf()
+
+ private fun updateLatestAnnouncement(new: Announcement) {
+ if (latestAnnouncement?.id?.value == new.id.value) {
+ latestAnnouncement = new
+ latestAnnouncementByChannel[new.channel ?: return] = new
+ }
+ }
+
+ init {
+ runBlocking {
+ transaction {
+ SchemaUtils.create(Announcements, Attachments)
+
+ // Initialize the latest announcement.
+ latestAnnouncement = Announcement.all().onEach {
+ latestAnnouncementByChannel[it.channel ?: return@onEach] = it
+ }.maxByOrNull { it.id } ?: return@transaction
+ }
+ }
+ }
+
+ suspend fun all() = transaction {
+ Announcement.all().map { it.toApi() }
+ }
+
+ suspend fun all(channel: String) = transaction {
+ Announcement.find { Announcements.channel eq channel }.map { it.toApi() }
+ }
+
+ suspend fun delete(id: Int) = transaction {
+ val announcement = Announcement.findById(id) ?: return@transaction
+
+ announcement.delete()
+
+ // In case the latest announcement was deleted, query the new latest announcement again.
+ if (latestAnnouncement?.id?.value == id) {
+ latestAnnouncement = Announcement.all().maxByOrNull { it.id }
+
+ // If no latest announcement was found, remove it from the channel map.
+ if (latestAnnouncement == null) {
+ latestAnnouncementByChannel.remove(announcement.channel)
+ } else {
+ latestAnnouncementByChannel[latestAnnouncement!!.channel ?: return@transaction] = latestAnnouncement!!
+ }
+ }
+ }
+
+ fun latest() = latestAnnouncement?.toApi()
+
+ fun latest(channel: String) = latestAnnouncementByChannel[channel]?.toApi()
+
+ fun latestId() = latest()?.id?.toApi()
+
+ fun latestId(channel: String) = latest(channel)?.id?.toApi()
+
+ suspend fun archive(
+ id: Int,
+ archivedAt: LocalDateTime?,
+ ) = transaction {
+ Announcement.findByIdAndUpdate(id) {
+ it.archivedAt = archivedAt ?: java.time.LocalDateTime.now().toKotlinLocalDateTime()
+ }?.also(::updateLatestAnnouncement)
+ }
+
+ suspend fun unarchive(id: Int) = transaction {
+ Announcement.findByIdAndUpdate(id) {
+ it.archivedAt = null
+ }?.also(::updateLatestAnnouncement)
+ }
+
+ suspend fun new(new: APIAnnouncement) = transaction {
+ Announcement.new {
+ author = new.author
+ title = new.title
+ content = new.content
+ channel = new.channel
+ archivedAt = new.archivedAt
+ level = new.level
+ }.also { newAnnouncement ->
+ new.attachmentUrls.map { newUrl ->
+ suspendedTransactionAsync {
+ Attachment.new {
+ url = newUrl
+ announcement = newAnnouncement
+ }
+ }
+ }.awaitAll()
+ }.also(::updateLatestAnnouncement)
+ }
+
+ suspend fun update(id: Int, new: APIAnnouncement) = transaction {
+ Announcement.findByIdAndUpdate(id) {
+ it.author = new.author
+ it.title = new.title
+ it.content = new.content
+ it.channel = new.channel
+ it.archivedAt = new.archivedAt
+ it.level = new.level
+ }?.also { newAnnouncement ->
+ newAnnouncement.attachments.map {
+ suspendedTransactionAsync {
+ it.delete()
+ }
+ }.awaitAll()
+
+ new.attachmentUrls.map { newUrl ->
+ suspendedTransactionAsync {
+ Attachment.new {
+ url = newUrl
+ announcement = newAnnouncement
+ }
+ }
+ }.awaitAll()
+ }?.also(::updateLatestAnnouncement)
+ }
+
+ private suspend fun transaction(statement: suspend Transaction.() -> T) =
+ newSuspendedTransaction(Dispatchers.IO, statement = statement)
+
+ private object Announcements : IntIdTable() {
+ val author = varchar("author", 32).nullable()
+ val title = varchar("title", 64)
+ val content = text("content").nullable()
+ val channel = varchar("channel", 16).nullable()
+ val createdAt = datetime("createdAt").defaultExpression(CurrentDateTime)
+ val archivedAt = datetime("archivedAt").nullable()
+ val level = integer("level")
+ }
+
+ private object Attachments : IntIdTable() {
+ val url = varchar("url", 256)
+ val announcement = reference("announcement", Announcements, onDelete = ReferenceOption.CASCADE)
+ }
+
+ class Announcement(id: EntityID) : IntEntity(id) {
+ companion object : IntEntityClass(Announcements)
+
+ var author by Announcements.author
+ var title by Announcements.title
+ var content by Announcements.content
+ val attachments by Attachment referrersOn Attachments.announcement
+ var channel by Announcements.channel
+ var createdAt by Announcements.createdAt
+ var archivedAt by Announcements.archivedAt
+ var level by Announcements.level
+ }
+
+ class Attachment(id: EntityID) : IntEntity(id) {
+ companion object : IntEntityClass(Attachments)
+
+ var url by Attachments.url
+ var announcement by Announcement referencedOn Attachments.announcement
+ }
+
+ private fun Announcement.toApi() = APIResponseAnnouncement(
+ id.value,
+ author,
+ title,
+ content,
+ attachments.map { it.url },
+ channel,
+ createdAt,
+ archivedAt,
+ level,
+ )
+
+ private fun Int.toApi() = APIResponseAnnouncementId(this)
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/repository/BackendRepository.kt b/src/main/kotlin/app/revanced/api/configuration/repository/BackendRepository.kt
new file mode 100644
index 00000000..69429ca3
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/repository/BackendRepository.kt
@@ -0,0 +1,172 @@
+package app.revanced.api.configuration.repository
+
+import io.ktor.client.*
+import kotlinx.datetime.LocalDateTime
+
+/**
+ * The backend of the API used to get data.
+ *
+ * @param client The HTTP client to use for requests.
+ */
+abstract class BackendRepository internal constructor(
+ protected val client: HttpClient,
+) {
+ /**
+ * A user.
+ *
+ * @property name The name of the user.
+ * @property avatarUrl The URL to the avatar of the user.
+ * @property url The URL to the profile of the user.
+ */
+ interface BackendUser {
+ val name: String
+ val avatarUrl: String
+ val url: String
+ }
+
+ /**
+ * An organization.
+ *
+ * @property members The members of the organization.
+ */
+ class BackendOrganization(
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val members: List,
+ ) {
+ /**
+ * A member of an organization.
+ *
+ * @property name The name of the member.
+ * @property avatarUrl The URL to the avatar of the member.
+ * @property url The URL to the profile of the member.
+ * @property bio The bio of the member.
+ * @property gpgKeys The GPG key of the member.
+ */
+ class BackendMember(
+ override val name: String,
+ override val avatarUrl: String,
+ override val url: String,
+ val bio: String?,
+ val gpgKeys: GpgKeys,
+ ) : BackendUser {
+ /**
+ * The GPG keys of a member.
+ *
+ * @property ids The IDs of the GPG keys.
+ * @property url The URL to the GPG master key.
+ */
+ class GpgKeys(
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val ids: List,
+ val url: String,
+ )
+ }
+
+ /**
+ * A repository of an organization.
+ *
+ * @property contributors The contributors of the repository.
+ */
+ class BackendRepository(
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val contributors: List,
+ ) {
+ /**
+ * A contributor of a repository.
+ *
+ * @property name The name of the contributor.
+ * @property avatarUrl The URL to the avatar of the contributor.
+ * @property url The URL to the profile of the contributor.
+ * @property contributions The number of contributions of the contributor.
+ */
+ class BackendContributor(
+ override val name: String,
+ override val avatarUrl: String,
+ override val url: String,
+ val contributions: Int,
+ ) : BackendUser
+
+ /**
+ * A release of a repository.
+ *
+ * @property tag The tag of the release.
+ * @property assets The assets of the release.
+ * @property createdAt The date and time the release was created.
+ * @property releaseNote The release note of the release.
+ */
+ class BackendRelease(
+ val tag: String,
+ val releaseNote: String,
+ val createdAt: LocalDateTime,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val assets: List,
+ ) {
+ companion object {
+ fun List.first(assetRegex: Regex) = first { assetRegex.containsMatchIn(it.name) }
+ }
+
+ /**
+ * An asset of a release.
+ *
+ * @property name The name of the asset.
+ * @property downloadUrl The URL to download the asset.
+ */
+ class BackendAsset(
+ val name: String,
+ val downloadUrl: String,
+ )
+ }
+ }
+ }
+
+ /**
+ * The rate limit of the backend.
+ *
+ * @property limit The limit of the rate limit.
+ * @property remaining The remaining requests of the rate limit.
+ * @property reset The date and time the rate limit resets.
+ */
+ class BackendRateLimit(
+ val limit: Int,
+ val remaining: Int,
+ val reset: LocalDateTime,
+ )
+
+ /**
+ * Get a release of a repository.
+ *
+ * @param owner The owner of the repository.
+ * @param repository The name of the repository.
+ * @param tag The tag of the release. If null, the latest release is returned.
+ * @return The release.
+ */
+ abstract suspend fun release(
+ owner: String,
+ repository: String,
+ tag: String? = null,
+ ): BackendOrganization.BackendRepository.BackendRelease
+
+ /**
+ * Get the contributors of a repository.
+ *
+ * @param owner The owner of the repository.
+ * @param repository The name of the repository.
+ * @return The contributors.
+ */
+ abstract suspend fun contributors(owner: String, repository: String): List
+
+ /**
+ * Get the members of an organization.
+ *
+ * @param organization The name of the organization.
+ * @return The members.
+ */
+ abstract suspend fun members(organization: String): List
+
+ /**
+ * Get the rate limit of the backend.
+ *
+ * @return The rate limit.
+ */
+ abstract suspend fun rateLimit(): BackendRateLimit?
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt b/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt
new file mode 100644
index 00000000..4e13cf64
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt
@@ -0,0 +1,110 @@
+package app.revanced.api.configuration.repository
+
+import app.revanced.api.configuration.services.ManagerService
+import app.revanced.api.configuration.services.PatchesService
+import kotlinx.serialization.KSerializer
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+import kotlinx.serialization.descriptors.PrimitiveKind
+import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
+import kotlinx.serialization.descriptors.SerialDescriptor
+import kotlinx.serialization.encoding.Decoder
+import kotlinx.serialization.encoding.Encoder
+import java.io.File
+
+/**
+ * The repository storing the configuration for the API.
+ *
+ * @property organization The API backends organization name where the repositories for the patches and integrations are.
+ * @property patches The source of the patches.
+ * @property integrations The source of the integrations.
+ * @property manager The source of the manager.
+ * @property contributorsRepositoryNames The names of the repositories to get contributors from.
+ * @property apiVersion The version to use for the API.
+ * @property corsAllowedHosts The hosts allowed to make requests to the API.
+ * @property endpoint The endpoint of the API.
+ * @property oldApiEndpoint The endpoint of the old API to proxy requests to.
+ */
+@Serializable
+internal class ConfigurationRepository(
+ val organization: String,
+ val patches: SignedAssetConfiguration,
+ val integrations: SignedAssetConfiguration,
+ val manager: AssetConfiguration,
+ @SerialName("contributors-repositories")
+ val contributorsRepositoryNames: Set,
+ @SerialName("api-version")
+ val apiVersion: Int = 1,
+ @SerialName("cors-allowed-hosts")
+ val corsAllowedHosts: Set,
+ val endpoint: String,
+ @SerialName("old-api-endpoint")
+ val oldApiEndpoint: String,
+) {
+ /**
+ * Am asset configuration whose asset is signed.
+ *
+ * [PatchesService] for example uses [BackendRepository] to get assets from its releases.
+ * A release contains multiple assets.
+ *
+ * This configuration is used in [ConfigurationRepository]
+ * to determine which release assets from repositories to get and to verify them.
+ *
+ * @property repository The repository in which releases are made to get an asset.
+ * @property assetRegex The regex matching the asset name.
+ * @property signatureAssetRegex The regex matching the signature asset name to verify the asset.
+ * @property publicKeyFile The public key file to verify the signature of the asset.
+ * @property publicKeyId The ID of the public key to verify the signature of the asset.
+ */
+ @Serializable
+ internal class SignedAssetConfiguration(
+ val repository: String,
+ @Serializable(with = RegexSerializer::class)
+ @SerialName("asset-regex")
+ val assetRegex: Regex,
+ @Serializable(with = RegexSerializer::class)
+ @SerialName("signature-asset-regex")
+ val signatureAssetRegex: Regex,
+ @Serializable(with = FileSerializer::class)
+ @SerialName("public-key-file")
+ val publicKeyFile: File,
+ @SerialName("public-key-id")
+ val publicKeyId: Long,
+ )
+
+ /**
+ * Am asset configuration.
+ *
+ * [ManagerService] for example uses [BackendRepository] to get assets from its releases.
+ * A release contains multiple assets.
+ *
+ * This configuration is used in [ConfigurationRepository]
+ * to determine which release assets from repositories to get and to verify them.
+ *
+ * @property repository The repository in which releases are made to get an asset.
+ * @property assetRegex The regex matching the asset name.
+ */
+ @Serializable
+ internal class AssetConfiguration(
+ val repository: String,
+ @Serializable(with = RegexSerializer::class)
+ @SerialName("asset-regex")
+ val assetRegex: Regex,
+ )
+}
+
+private object RegexSerializer : KSerializer {
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Regex", PrimitiveKind.STRING)
+
+ override fun serialize(encoder: Encoder, value: Regex) = encoder.encodeString(value.pattern)
+
+ override fun deserialize(decoder: Decoder) = Regex(decoder.decodeString())
+}
+
+private object FileSerializer : KSerializer {
+ override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("File", PrimitiveKind.STRING)
+
+ override fun serialize(encoder: Encoder, value: File) = encoder.encodeString(value.path)
+
+ override fun deserialize(decoder: Decoder) = File(decoder.decodeString())
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/repository/GitHubBackendRepository.kt b/src/main/kotlin/app/revanced/api/configuration/repository/GitHubBackendRepository.kt
new file mode 100644
index 00000000..d5d91489
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/repository/GitHubBackendRepository.kt
@@ -0,0 +1,208 @@
+package app.revanced.api.configuration.repository
+
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendMember
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendContributor
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendRelease
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendRelease.BackendAsset
+import app.revanced.api.configuration.repository.GitHubOrganization.GitHubRepository.GitHubContributor
+import app.revanced.api.configuration.repository.GitHubOrganization.GitHubRepository.GitHubRelease
+import app.revanced.api.configuration.repository.Organization.Repository.Contributors
+import app.revanced.api.configuration.repository.Organization.Repository.Releases
+import io.ktor.client.*
+import io.ktor.client.call.*
+import io.ktor.client.plugins.resources.*
+import io.ktor.resources.*
+import kotlinx.coroutines.*
+import kotlinx.datetime.Instant
+import kotlinx.datetime.TimeZone
+import kotlinx.datetime.toLocalDateTime
+import kotlinx.serialization.SerialName
+import kotlinx.serialization.Serializable
+
+class GitHubBackendRepository(client: HttpClient) : BackendRepository(client) {
+ override suspend fun release(
+ owner: String,
+ repository: String,
+ tag: String?,
+ ): BackendRelease {
+ val release: GitHubRelease = if (tag != null) {
+ client.get(Releases.Tag(owner, repository, tag)).body()
+ } else {
+ client.get(Releases.Latest(owner, repository)).body()
+ }
+
+ return BackendRelease(
+ tag = release.tagName,
+ releaseNote = release.body,
+ createdAt = release.createdAt.toLocalDateTime(TimeZone.UTC),
+ assets = release.assets.map {
+ BackendAsset(
+ name = it.name,
+ downloadUrl = it.browserDownloadUrl,
+ )
+ },
+ )
+ }
+
+ override suspend fun contributors(
+ owner: String,
+ repository: String,
+ ): List {
+ val contributors: List = client.get(
+ Contributors(
+ owner,
+ repository,
+ ),
+ ).body()
+
+ return contributors.map {
+ BackendContributor(
+ name = it.login,
+ avatarUrl = it.avatarUrl,
+ url = it.htmlUrl,
+ contributions = it.contributions,
+ )
+ }
+ }
+
+ override suspend fun members(organization: String): List {
+ // Get the list of members of the organization.
+ val publicMembers: List = client.get(Organization.PublicMembers(organization)).body()
+
+ return coroutineScope {
+ publicMembers.map { member ->
+ async {
+ awaitAll(
+ async {
+ // Get the user.
+ client.get(User(member.login)).body()
+ },
+ async {
+ // Get the GPG key of the user.
+ client.get(User.GpgKeys(member.login)).body>()
+ },
+ )
+ }
+ }
+ }.awaitAll().map { responses ->
+ val user = responses[0] as GitHubUser
+
+ @Suppress("UNCHECKED_CAST")
+ val gpgKeys = responses[1] as List
+
+ BackendMember(
+ name = user.login,
+ avatarUrl = user.avatarUrl,
+ url = user.htmlUrl,
+ bio = user.bio,
+ gpgKeys =
+ BackendMember.GpgKeys(
+ ids = gpgKeys.map { it.keyId },
+ url = "https://api.github.com/users/${user.login}.gpg",
+ ),
+ )
+ }
+ }
+
+ override suspend fun rateLimit(): BackendRateLimit {
+ val rateLimit: GitHubRateLimit = client.get(RateLimit()).body()
+
+ return BackendRateLimit(
+ limit = rateLimit.rate.limit,
+ remaining = rateLimit.rate.remaining,
+ reset = Instant.fromEpochSeconds(rateLimit.rate.reset).toLocalDateTime(TimeZone.UTC),
+ )
+ }
+}
+
+interface IGitHubUser {
+ val login: String
+ val avatarUrl: String
+ val htmlUrl: String
+}
+
+@Serializable
+class GitHubUser(
+ override val login: String,
+ override val avatarUrl: String,
+ override val htmlUrl: String,
+ val bio: String?,
+) : IGitHubUser {
+ @Serializable
+ class GitHubGpgKey(
+ val keyId: String,
+ )
+}
+
+class GitHubOrganization {
+ @Serializable
+ class GitHubMember(
+ override val login: String,
+ override val avatarUrl: String,
+ override val htmlUrl: String,
+ ) : IGitHubUser
+
+ class GitHubRepository {
+ @Serializable
+ class GitHubContributor(
+ override val login: String,
+ override val avatarUrl: String,
+ override val htmlUrl: String,
+ val contributions: Int,
+ ) : IGitHubUser
+
+ @Serializable
+ class GitHubRelease(
+ val tagName: String,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val assets: List,
+ val createdAt: Instant,
+ val body: String,
+ ) {
+ @Serializable
+ class GitHubAsset(
+ val name: String,
+ val browserDownloadUrl: String,
+ )
+ }
+ }
+}
+
+@Serializable
+class GitHubRateLimit(
+ val rate: Rate,
+) {
+ @Serializable
+ class Rate(
+ val limit: Int,
+ val remaining: Int,
+ val reset: Long,
+ )
+}
+
+@Resource("/users/{login}")
+class User(val login: String) {
+ @Resource("/users/{login}/gpg_keys")
+ class GpgKeys(val login: String)
+}
+
+class Organization {
+ @Resource("/orgs/{org}/public_members")
+ class PublicMembers(val org: String)
+
+ class Repository {
+ @Resource("/repos/{owner}/{repo}/contributors")
+ class Contributors(val owner: String, val repo: String, @SerialName("per_page") val perPage: Int = 100)
+
+ class Releases {
+ @Resource("/repos/{owner}/{repo}/releases/tags/{tag}")
+ class Tag(val owner: String, val repo: String, val tag: String)
+
+ @Resource("/repos/{owner}/{repo}/releases/latest")
+ class Latest(val owner: String, val repo: String)
+ }
+ }
+}
+
+@Resource("/rate_limit")
+class RateLimit
diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/Announcements.kt b/src/main/kotlin/app/revanced/api/configuration/routes/Announcements.kt
new file mode 100644
index 00000000..938d5565
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/routes/Announcements.kt
@@ -0,0 +1,390 @@
+package app.revanced.api.configuration.routes
+
+import app.revanced.api.configuration.installCache
+import app.revanced.api.configuration.installNotarizedRoute
+import app.revanced.api.configuration.respondOrNotFound
+import app.revanced.api.configuration.schema.APIAnnouncement
+import app.revanced.api.configuration.schema.APIAnnouncementArchivedAt
+import app.revanced.api.configuration.schema.APIResponseAnnouncement
+import app.revanced.api.configuration.schema.APIResponseAnnouncementId
+import app.revanced.api.configuration.services.AnnouncementService
+import io.bkbn.kompendium.core.metadata.DeleteInfo
+import io.bkbn.kompendium.core.metadata.GetInfo
+import io.bkbn.kompendium.core.metadata.PatchInfo
+import io.bkbn.kompendium.core.metadata.PostInfo
+import io.bkbn.kompendium.json.schema.definition.TypeDefinition
+import io.bkbn.kompendium.oas.payload.Parameter
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.auth.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.request.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import io.ktor.server.util.*
+import kotlin.time.Duration.Companion.minutes
+import org.koin.ktor.ext.get as koinGet
+
+internal fun Route.announcementsRoute() = route("announcements") {
+ val announcementService = koinGet()
+
+ installCache(5.minutes)
+
+ installAnnouncementsRouteDocumentation()
+
+ rateLimit(RateLimitName("strong")) {
+ get {
+ call.respond(announcementService.all())
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ route("{channel}/latest") {
+ installLatestChannelAnnouncementRouteDocumentation()
+
+ get {
+ val channel: String by call.parameters
+
+ call.respondOrNotFound(announcementService.latest(channel))
+ }
+
+ route("id") {
+ installLatestChannelAnnouncementIdRouteDocumentation()
+
+ get {
+ val channel: String by call.parameters
+
+ call.respondOrNotFound(announcementService.latestId(channel))
+ }
+ }
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ route("{channel}") {
+ installChannelAnnouncementsRouteDocumentation()
+
+ get {
+ val channel: String by call.parameters
+
+ call.respond(announcementService.all(channel))
+ }
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ route("latest") {
+ installLatestAnnouncementRouteDocumentation()
+
+ get {
+ call.respondOrNotFound(announcementService.latest())
+ }
+
+ route("id") {
+ installLatestAnnouncementIdRouteDocumentation()
+
+ get {
+ call.respondOrNotFound(announcementService.latestId())
+ }
+ }
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ authenticate("jwt") {
+ installAnnouncementRouteDocumentation()
+
+ post { announcement ->
+ announcementService.new(announcement)
+ }
+
+ route("{id}") {
+ installAnnouncementIdRouteDocumentation()
+
+ patch { announcement ->
+ val id: Int by call.parameters
+
+ announcementService.update(id, announcement)
+ }
+
+ delete {
+ val id: Int by call.parameters
+
+ announcementService.delete(id)
+ }
+
+ route("archive") {
+ installAnnouncementArchiveRouteDocumentation()
+
+ post {
+ val id: Int by call.parameters
+ val archivedAt = call.receiveNullable()?.archivedAt
+
+ announcementService.archive(id, archivedAt)
+ }
+ }
+
+ route("unarchive") {
+ installAnnouncementUnarchiveRouteDocumentation()
+
+ post {
+ val id: Int by call.parameters
+
+ announcementService.unarchive(id)
+ }
+ }
+ }
+ }
+ }
+}
+
+private fun Route.installAnnouncementRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ post = PostInfo.builder {
+ description("Create a new announcement")
+ summary("Create announcement")
+ request {
+ requestType()
+ description("The new announcement")
+ }
+ response {
+ description("When the announcement was created")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installLatestAnnouncementRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ get = GetInfo.builder {
+ description("Get the latest announcement")
+ summary("Get latest announcement")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The latest announcement")
+ responseType()
+ }
+ canRespond {
+ responseCode(HttpStatusCode.NotFound)
+ description("No announcement exists")
+ responseType()
+ }
+ }
+}
+
+private fun Route.installLatestAnnouncementIdRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ get = GetInfo.builder {
+ description("Get the id of the latest announcement")
+ summary("Get id of latest announcement")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The id of the latest announcement")
+ responseType()
+ }
+ canRespond {
+ responseCode(HttpStatusCode.NotFound)
+ description("No announcement exists")
+ responseType()
+ }
+ }
+}
+
+private fun Route.installChannelAnnouncementsRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "channel",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.STRING,
+ description = "The channel to get the announcements from",
+ required = true,
+ ),
+ )
+
+ get = GetInfo.builder {
+ description("Get the announcements from a channel")
+ summary("Get announcements from channel")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The announcements in the channel")
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installAnnouncementArchiveRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "id",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.INT,
+ description = "The id of the announcement to archive",
+ required = true,
+ ),
+ Parameter(
+ name = "archivedAt",
+ `in` = Parameter.Location.query,
+ schema = TypeDefinition.STRING,
+ description = "The date and time the announcement to be archived",
+ required = false,
+ ),
+ )
+
+ post = PostInfo.builder {
+ description("Archive an announcement")
+ summary("Archive announcement")
+ response {
+ description("When the announcement was archived")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installAnnouncementUnarchiveRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "id",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.INT,
+ description = "The id of the announcement to unarchive",
+ required = true,
+ ),
+ )
+
+ post = PostInfo.builder {
+ description("Unarchive an announcement")
+ summary("Unarchive announcement")
+ response {
+ description("When announcement was unarchived")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installAnnouncementIdRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "id",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.INT,
+ description = "The id of the announcement to update",
+ required = true,
+ ),
+ )
+
+ patch = PatchInfo.builder {
+ description("Update an announcement")
+ summary("Update announcement")
+ request {
+ requestType()
+ description("The new announcement")
+ }
+ response {
+ description("When announcement was updated")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+
+ delete = DeleteInfo.builder {
+ description("Delete an announcement")
+ summary("Delete announcement")
+ response {
+ description("When the announcement was deleted")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installAnnouncementsRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ get = GetInfo.builder {
+ description("Get the announcements")
+ summary("Get announcements")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The announcements")
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installLatestChannelAnnouncementRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "channel",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.STRING,
+ description = "The channel to get the latest announcement from",
+ required = true,
+ ),
+ )
+
+ get = GetInfo.builder {
+ description("Get the latest announcement from a channel")
+ summary("Get latest channel announcement")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The latest announcement in the channel")
+ responseType()
+ }
+ canRespond {
+ responseCode(HttpStatusCode.NotFound)
+ description("The channel does not exist")
+ responseType()
+ }
+ }
+}
+
+private fun Route.installLatestChannelAnnouncementIdRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Announcements")
+
+ parameters = listOf(
+ Parameter(
+ name = "channel",
+ `in` = Parameter.Location.path,
+ schema = TypeDefinition.STRING,
+ description = "The channel to get the latest announcement id from",
+ required = true,
+ ),
+ )
+
+ get = GetInfo.builder {
+ description("Get the id of the latest announcement from a channel")
+ summary("Get id of latest announcement from channel")
+ response {
+ responseCode(HttpStatusCode.OK)
+ mediaTypes("application/json")
+ description("The id of the latest announcement from the channel")
+ responseType()
+ }
+ canRespond {
+ responseCode(HttpStatusCode.NotFound)
+ description("The channel does not exist")
+ responseType()
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/ApiRoute.kt b/src/main/kotlin/app/revanced/api/configuration/routes/ApiRoute.kt
new file mode 100644
index 00000000..5152d654
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/routes/ApiRoute.kt
@@ -0,0 +1,157 @@
+package app.revanced.api.configuration.routes
+
+import app.revanced.api.configuration.installCache
+import app.revanced.api.configuration.installNoCache
+import app.revanced.api.configuration.installNotarizedRoute
+import app.revanced.api.configuration.respondOrNotFound
+import app.revanced.api.configuration.schema.APIContributable
+import app.revanced.api.configuration.schema.APIMember
+import app.revanced.api.configuration.schema.APIRateLimit
+import app.revanced.api.configuration.services.ApiService
+import app.revanced.api.configuration.services.AuthService
+import io.bkbn.kompendium.core.metadata.*
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.auth.*
+import io.ktor.server.http.content.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import kotlin.time.Duration.Companion.days
+import org.koin.ktor.ext.get as koinGet
+
+internal fun Route.apiRoute() {
+ val apiService = koinGet()
+ val authService = koinGet()
+
+ rateLimit(RateLimitName("strong")) {
+ authenticate("auth-digest") {
+ route("token") {
+ installTokenRouteDocumentation()
+
+ get {
+ call.respond(authService.newToken())
+ }
+ }
+ }
+
+ route("contributors") {
+ installCache(1.days)
+
+ installContributorsRouteDocumentation()
+
+ get {
+ call.respond(apiService.contributors())
+ }
+ }
+
+ route("team") {
+ installCache(1.days)
+
+ installTeamRouteDocumentation()
+
+ get {
+ call.respond(apiService.team())
+ }
+ }
+ }
+
+ route("ping") {
+ installNoCache()
+
+ installPingRouteDocumentation()
+
+ head {
+ call.respond(HttpStatusCode.NoContent)
+ }
+ }
+
+ rateLimit(RateLimitName("weak")) {
+ route("backend/rate_limit") {
+ installRateLimitRouteDocumentation()
+
+ get {
+ call.respondOrNotFound(apiService.rateLimit())
+ }
+ }
+
+ staticResources("/", "/app/revanced/api/static/versioned") {
+ contentType { ContentType.Application.Json }
+ extensions("json")
+ }
+ }
+}
+
+private fun Route.installRateLimitRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("API")
+
+ get = GetInfo.builder {
+ description("Get the rate limit of the backend")
+ summary("Get rate limit of backend")
+ response {
+ description("The rate limit of the backend")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installPingRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("API")
+
+ head = HeadInfo.builder {
+ description("Ping the server")
+ summary("Ping")
+ response {
+ description("The server is reachable")
+ responseCode(HttpStatusCode.NoContent)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installTeamRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("API")
+
+ get = GetInfo.builder {
+ description("Get the list of team members")
+ summary("Get team members")
+ response {
+ description("The list of team members")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installContributorsRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("API")
+
+ get = GetInfo.builder {
+ description("Get the list of contributors")
+ summary("Get contributors")
+ response {
+ description("The list of contributors")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installTokenRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("API")
+
+ get = GetInfo.builder {
+ description("Get a new authorization token")
+ summary("Get authorization token")
+ response {
+ description("The authorization token")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt b/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt
new file mode 100644
index 00000000..b87024cf
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt
@@ -0,0 +1,66 @@
+package app.revanced.api.configuration.routes
+
+import app.revanced.api.configuration.installNotarizedRoute
+import app.revanced.api.configuration.schema.APIManagerAsset
+import app.revanced.api.configuration.schema.APIRelease
+import app.revanced.api.configuration.schema.APIReleaseVersion
+import app.revanced.api.configuration.services.ManagerService
+import io.bkbn.kompendium.core.metadata.GetInfo
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import org.koin.ktor.ext.get as koinGet
+
+internal fun Route.managerRoute() = route("manager") {
+ val managerService = koinGet()
+
+ route("latest") {
+ installLatestManagerRouteDocumentation()
+
+ rateLimit(RateLimitName("weak")) {
+ get {
+ call.respond(managerService.latestRelease())
+ }
+
+ route("version") {
+ installLatestManagerVersionRouteDocumentation()
+
+ get {
+ call.respond(managerService.latestVersion())
+ }
+ }
+ }
+ }
+}
+
+private fun Route.installLatestManagerRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Manager")
+
+ get = GetInfo.builder {
+ description("Get the latest manager release")
+ summary("Get latest manager release")
+ response {
+ description("The latest manager release")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installLatestManagerVersionRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Manager")
+
+ get = GetInfo.builder {
+ description("Get the latest manager release version")
+ summary("Get latest manager release version")
+ response {
+ description("The latest manager release version")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/OldApi.kt b/src/main/kotlin/app/revanced/api/configuration/routes/OldApi.kt
new file mode 100644
index 00000000..e72f470e
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/routes/OldApi.kt
@@ -0,0 +1,19 @@
+package app.revanced.api.configuration.routes
+
+import app.revanced.api.configuration.services.OldApiService
+import io.ktor.server.application.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.routing.*
+import org.koin.ktor.ext.get
+
+internal fun Route.oldApiRoute() {
+ val oldApiService = get()
+
+ rateLimit(RateLimitName("weak")) {
+ route(Regex("/(v2|tools|contributors).*")) {
+ handle {
+ oldApiService.proxy(call)
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/PatchesRoute.kt b/src/main/kotlin/app/revanced/api/configuration/routes/PatchesRoute.kt
new file mode 100644
index 00000000..b1ff8412
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/routes/PatchesRoute.kt
@@ -0,0 +1,121 @@
+package app.revanced.api.configuration.routes
+
+import app.revanced.api.configuration.installCache
+import app.revanced.api.configuration.installNotarizedRoute
+import app.revanced.api.configuration.schema.APIAssetPublicKeys
+import app.revanced.api.configuration.schema.APIPatchesAsset
+import app.revanced.api.configuration.schema.APIRelease
+import app.revanced.api.configuration.schema.APIReleaseVersion
+import app.revanced.api.configuration.services.PatchesService
+import io.bkbn.kompendium.core.metadata.GetInfo
+import io.ktor.http.*
+import io.ktor.server.application.*
+import io.ktor.server.plugins.ratelimit.*
+import io.ktor.server.response.*
+import io.ktor.server.routing.*
+import kotlin.time.Duration.Companion.days
+import org.koin.ktor.ext.get as koinGet
+
+internal fun Route.patchesRoute() = route("patches") {
+ val patchesService = koinGet()
+
+ route("latest") {
+ installLatestPatchesRouteDocumentation()
+
+ rateLimit(RateLimitName("weak")) {
+ get {
+ call.respond(patchesService.latestRelease())
+ }
+
+ route("version") {
+ installLatestPatchesVersionRouteDocumentation()
+
+ get {
+ call.respond(patchesService.latestVersion())
+ }
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ route("list") {
+ installLatestPatchesListRouteDocumentation()
+
+ get {
+ call.respondBytes(ContentType.Application.Json) { patchesService.list() }
+ }
+ }
+ }
+ }
+
+ rateLimit(RateLimitName("strong")) {
+ route("keys") {
+ installCache(356.days)
+
+ installPatchesPublicKeyRouteDocumentation()
+
+ get {
+ call.respond(patchesService.publicKeys())
+ }
+ }
+ }
+}
+
+private fun Route.installLatestPatchesRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Patches")
+
+ get = GetInfo.builder {
+ description("Get the latest patches release")
+ summary("Get latest patches release")
+ response {
+ description("The latest patches release")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType>()
+ }
+ }
+}
+
+private fun Route.installLatestPatchesVersionRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Patches")
+
+ get = GetInfo.builder {
+ description("Get the latest patches release version")
+ summary("Get latest patches release version")
+ response {
+ description("The latest patches release version")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installLatestPatchesListRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Patches")
+
+ get = GetInfo.builder {
+ description("Get the list of patches from the latest patches release")
+ summary("Get list of patches from latest patches release")
+ response {
+ description("The list of patches")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
+
+private fun Route.installPatchesPublicKeyRouteDocumentation() = installNotarizedRoute {
+ tags = setOf("Patches")
+
+ get = GetInfo.builder {
+ description("Get the public keys for verifying patches and integrations assets")
+ summary("Get patches and integrations public keys")
+ response {
+ description("The public keys")
+ mediaTypes("application/json")
+ responseCode(HttpStatusCode.OK)
+ responseType()
+ }
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/schema/APISchema.kt b/src/main/kotlin/app/revanced/api/configuration/schema/APISchema.kt
new file mode 100644
index 00000000..d6d28ef3
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/schema/APISchema.kt
@@ -0,0 +1,122 @@
+package app.revanced.api.configuration.schema
+
+import kotlinx.datetime.LocalDateTime
+import kotlinx.serialization.Serializable
+
+interface APIUser {
+ val name: String
+ val avatarUrl: String
+ val url: String
+}
+
+@Serializable
+class APIMember(
+ override val name: String,
+ override val avatarUrl: String,
+ override val url: String,
+ val bio: String?,
+ val gpgKey: APIGpgKey?,
+) : APIUser
+
+@Serializable
+class APIGpgKey(
+ val id: String,
+ val url: String,
+)
+
+@Serializable
+class APIContributor(
+ override val name: String,
+ override val avatarUrl: String,
+ override val url: String,
+ val contributions: Int,
+) : APIUser
+
+@Serializable
+class APIContributable(
+ val name: String,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val contributors: List,
+)
+
+@Serializable
+class APIRelease(
+ val version: String,
+ val createdAt: LocalDateTime,
+ val description: String,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val assets: List,
+)
+
+@Serializable
+class APIManagerAsset(
+ val downloadUrl: String,
+)
+
+@Serializable
+class APIPatchesAsset(
+ val downloadUrl: String,
+ val signatureDownloadUrl: String,
+ // TODO: Remove this eventually when integrations are merged into patches.
+ val name: APIAssetName,
+)
+
+@Serializable
+enum class APIAssetName {
+ PATCHES,
+ INTEGRATION,
+}
+
+@Serializable
+class APIReleaseVersion(
+ val version: String,
+)
+
+@Serializable
+class APIAnnouncement(
+ val author: String? = null,
+ val title: String,
+ val content: String? = null,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val attachmentUrls: List = emptyList(),
+ val channel: String? = null,
+ val archivedAt: LocalDateTime? = null,
+ val level: Int = 0,
+)
+
+@Serializable
+class APIResponseAnnouncement(
+ val id: Int,
+ val author: String? = null,
+ val title: String,
+ val content: String? = null,
+ // Using a list instead of a set because set semantics are unnecessary here.
+ val attachmentUrls: List = emptyList(),
+ val channel: String? = null,
+ val createdAt: LocalDateTime,
+ val archivedAt: LocalDateTime? = null,
+ val level: Int = 0,
+)
+
+@Serializable
+class APIResponseAnnouncementId(
+ val id: Int,
+)
+
+@Serializable
+class APIAnnouncementArchivedAt(
+ val archivedAt: LocalDateTime,
+)
+
+@Serializable
+class APIRateLimit(
+ val limit: Int,
+ val remaining: Int,
+ val reset: LocalDateTime,
+)
+
+@Serializable
+class APIAssetPublicKeys(
+ val patchesPublicKey: String,
+ val integrationsPublicKey: String,
+)
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/AnnouncementService.kt b/src/main/kotlin/app/revanced/api/configuration/services/AnnouncementService.kt
new file mode 100644
index 00000000..909cff8a
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/AnnouncementService.kt
@@ -0,0 +1,35 @@
+package app.revanced.api.configuration.services
+
+import app.revanced.api.configuration.repository.AnnouncementRepository
+import app.revanced.api.configuration.schema.APIAnnouncement
+import app.revanced.api.configuration.schema.APIResponseAnnouncementId
+import kotlinx.datetime.LocalDateTime
+
+internal class AnnouncementService(
+ private val announcementRepository: AnnouncementRepository,
+) {
+ fun latestId(channel: String): APIResponseAnnouncementId? = announcementRepository.latestId(channel)
+ fun latestId(): APIResponseAnnouncementId? = announcementRepository.latestId()
+
+ fun latest(channel: String) = announcementRepository.latest(channel)
+ fun latest() = announcementRepository.latest()
+
+ suspend fun all(channel: String) = announcementRepository.all(channel)
+ suspend fun all() = announcementRepository.all()
+
+ suspend fun new(new: APIAnnouncement) {
+ announcementRepository.new(new)
+ }
+ suspend fun archive(id: Int, archivedAt: LocalDateTime?) {
+ announcementRepository.archive(id, archivedAt)
+ }
+ suspend fun unarchive(id: Int) {
+ announcementRepository.unarchive(id)
+ }
+ suspend fun update(id: Int, new: APIAnnouncement) {
+ announcementRepository.update(id, new)
+ }
+ suspend fun delete(id: Int) {
+ announcementRepository.delete(id)
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/ApiService.kt b/src/main/kotlin/app/revanced/api/configuration/services/ApiService.kt
new file mode 100644
index 00000000..0a73fff9
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/ApiService.kt
@@ -0,0 +1,49 @@
+package app.revanced.api.configuration.services
+
+import app.revanced.api.configuration.repository.BackendRepository
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import app.revanced.api.configuration.schema.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.async
+import kotlinx.coroutines.awaitAll
+import kotlinx.coroutines.withContext
+
+internal class ApiService(
+ private val backendRepository: BackendRepository,
+ private val configurationRepository: ConfigurationRepository,
+) {
+ suspend fun contributors() = withContext(Dispatchers.IO) {
+ configurationRepository.contributorsRepositoryNames.map {
+ async {
+ APIContributable(
+ it,
+ backendRepository.contributors(configurationRepository.organization, it).map {
+ APIContributor(it.name, it.avatarUrl, it.url, it.contributions)
+ },
+ )
+ }
+ }
+ }.awaitAll()
+
+ suspend fun team() = backendRepository.members(configurationRepository.organization).map { member ->
+ APIMember(
+ member.name,
+ member.avatarUrl,
+ member.url,
+ member.bio,
+ if (member.gpgKeys.ids.isNotEmpty()) {
+ APIGpgKey(
+ // Must choose one of the GPG keys, because it does not make sense to have multiple GPG keys for the API.
+ member.gpgKeys.ids.first(),
+ member.gpgKeys.url,
+ )
+ } else {
+ null
+ },
+ )
+ }
+
+ suspend fun rateLimit() = backendRepository.rateLimit()?.let {
+ APIRateLimit(it.limit, it.remaining, it.reset)
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/AuthService.kt b/src/main/kotlin/app/revanced/api/configuration/services/AuthService.kt
new file mode 100644
index 00000000..55e43951
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/AuthService.kt
@@ -0,0 +1,49 @@
+package app.revanced.api.configuration.services
+
+import com.auth0.jwt.JWT
+import com.auth0.jwt.algorithms.Algorithm
+import io.ktor.server.application.*
+import io.ktor.server.auth.*
+import io.ktor.server.auth.jwt.*
+import java.util.*
+import kotlin.text.HexFormat
+import kotlin.time.Duration.Companion.minutes
+
+internal class AuthService private constructor(
+ private val issuer: String,
+ private val validityInMin: Int,
+ private val jwtSecret: String,
+ private val authSHA256Digest: ByteArray,
+) {
+ @OptIn(ExperimentalStdlibApi::class)
+ constructor(issuer: String, validityInMin: Int, jwtSecret: String, authSHA256DigestString: String) : this(
+ issuer,
+ validityInMin,
+ jwtSecret,
+ authSHA256DigestString.hexToByteArray(HexFormat.Default),
+ )
+
+ val configureSecurity: Application.() -> Unit = {
+ install(Authentication) {
+ jwt("jwt") {
+ realm = "ReVanced"
+
+ verifier(JWT.require(Algorithm.HMAC256(jwtSecret)).withIssuer(issuer).build())
+ }
+
+ digest("auth-digest") {
+ realm = "ReVanced"
+ algorithmName = "SHA-256"
+
+ digestProvider { _, _ ->
+ authSHA256Digest
+ }
+ }
+ }
+ }
+
+ fun newToken(): String = JWT.create()
+ .withIssuer(issuer)
+ .withExpiresAt(Date(System.currentTimeMillis() + validityInMin.minutes.inWholeMilliseconds))
+ .sign(Algorithm.HMAC256(jwtSecret))
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt b/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt
new file mode 100644
index 00000000..17b06650
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt
@@ -0,0 +1,38 @@
+package app.revanced.api.configuration.services
+
+import app.revanced.api.configuration.repository.BackendRepository
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendRelease.Companion.first
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import app.revanced.api.configuration.schema.*
+
+internal class ManagerService(
+ private val backendRepository: BackendRepository,
+ private val configurationRepository: ConfigurationRepository,
+) {
+ suspend fun latestRelease(): APIRelease {
+ val managerRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.manager.repository,
+ )
+
+ val managerAsset = APIManagerAsset(
+ managerRelease.assets.first(configurationRepository.manager.assetRegex).downloadUrl,
+ )
+
+ return APIRelease(
+ managerRelease.tag,
+ managerRelease.createdAt,
+ managerRelease.releaseNote,
+ listOf(managerAsset),
+ )
+ }
+
+ suspend fun latestVersion(): APIReleaseVersion {
+ val managerRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.manager.repository,
+ )
+
+ return APIReleaseVersion(managerRelease.tag)
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/OldApiService.kt b/src/main/kotlin/app/revanced/api/configuration/services/OldApiService.kt
new file mode 100644
index 00000000..2c464aa9
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/OldApiService.kt
@@ -0,0 +1,69 @@
+package app.revanced.api.configuration.services
+
+import io.ktor.client.*
+import io.ktor.client.request.*
+import io.ktor.client.statement.*
+import io.ktor.http.*
+import io.ktor.http.content.*
+import io.ktor.server.application.*
+import io.ktor.server.request.*
+import io.ktor.server.response.*
+import io.ktor.util.*
+import io.ktor.utils.io.*
+
+internal class OldApiService(private val client: HttpClient) {
+ @OptIn(InternalAPI::class)
+ suspend fun proxy(call: ApplicationCall) {
+ val channel = call.request.receiveChannel()
+ val size = channel.availableForRead
+ val byteArray = ByteArray(size)
+ channel.readFully(byteArray)
+
+ val response: HttpResponse = client.request(call.request.uri) {
+ method = call.request.httpMethod
+
+ headers {
+ appendAll(
+ call.request.headers.filter { key, _ ->
+ !(
+ key.equals(HttpHeaders.ContentType, ignoreCase = true) ||
+ key.equals(HttpHeaders.ContentLength, ignoreCase = true) ||
+ key.equals(HttpHeaders.Host, ignoreCase = true)
+ )
+ },
+ )
+ }
+
+ when (call.request.httpMethod) {
+ HttpMethod.Post,
+ HttpMethod.Put,
+ HttpMethod.Patch,
+ HttpMethod.Delete,
+ -> body = ByteArrayContent(byteArray, call.request.contentType())
+ }
+ }
+
+ val headers = response.headers
+
+ call.respond(object : OutgoingContent.WriteChannelContent() {
+ override val contentLength: Long? = headers[HttpHeaders.ContentLength]?.toLong()
+ override val contentType = headers[HttpHeaders.ContentType]?.let { ContentType.parse(it) }
+ override val headers: Headers = Headers.build {
+ appendAll(
+ headers.filter { key, _ ->
+ !key.equals(
+ HttpHeaders.ContentType,
+ ignoreCase = true,
+ ) &&
+ !key.equals(HttpHeaders.ContentLength, ignoreCase = true)
+ },
+ )
+ }
+ override val status = response.status
+
+ override suspend fun writeTo(channel: ByteWriteChannel) {
+ response.content.copyAndClose(channel)
+ }
+ })
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/PatchesService.kt b/src/main/kotlin/app/revanced/api/configuration/services/PatchesService.kt
new file mode 100644
index 00000000..618fc335
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/PatchesService.kt
@@ -0,0 +1,124 @@
+package app.revanced.api.configuration.services
+
+import app.revanced.api.configuration.repository.BackendRepository
+import app.revanced.api.configuration.repository.BackendRepository.BackendOrganization.BackendRepository.BackendRelease.Companion.first
+import app.revanced.api.configuration.repository.ConfigurationRepository
+import app.revanced.api.configuration.schema.*
+import app.revanced.library.PatchUtils
+import app.revanced.patcher.PatchBundleLoader
+import com.github.benmanes.caffeine.cache.Caffeine
+import io.ktor.util.*
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.withContext
+import java.io.ByteArrayOutputStream
+import java.net.URL
+
+internal class PatchesService(
+ private val signatureService: SignatureService,
+ private val backendRepository: BackendRepository,
+ private val configurationRepository: ConfigurationRepository,
+) {
+ suspend fun latestRelease(): APIRelease {
+ val patchesRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.patches.repository,
+ )
+
+ val integrationsRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.integrations.repository,
+ )
+
+ fun ConfigurationRepository.SignedAssetConfiguration.asset(
+ release: BackendRepository.BackendOrganization.BackendRepository.BackendRelease,
+ assetName: APIAssetName,
+ ) = APIPatchesAsset(
+ release.assets.first(assetRegex).downloadUrl,
+ release.assets.first(signatureAssetRegex).downloadUrl,
+ assetName,
+ )
+
+ val patchesAsset = configurationRepository.patches.asset(
+ patchesRelease,
+ APIAssetName.PATCHES,
+ )
+ val integrationsAsset = configurationRepository.integrations.asset(
+ integrationsRelease,
+ APIAssetName.INTEGRATION,
+ )
+
+ return APIRelease(
+ patchesRelease.tag,
+ patchesRelease.createdAt,
+ patchesRelease.releaseNote,
+ listOf(patchesAsset, integrationsAsset),
+ )
+ }
+
+ suspend fun latestVersion(): APIReleaseVersion {
+ val patchesRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.patches.repository,
+ )
+
+ return APIReleaseVersion(patchesRelease.tag)
+ }
+
+ private val patchesListCache = Caffeine
+ .newBuilder()
+ .maximumSize(1)
+ .build()
+
+ suspend fun list(): ByteArray {
+ val patchesRelease = backendRepository.release(
+ configurationRepository.organization,
+ configurationRepository.patches.repository,
+ )
+
+ return withContext(Dispatchers.IO) {
+ patchesListCache.get(patchesRelease.tag) {
+ val patchesDownloadUrl = patchesRelease.assets
+ .first(configurationRepository.patches.assetRegex).downloadUrl
+
+ val signatureDownloadUrl = patchesRelease.assets
+ .first(configurationRepository.patches.signatureAssetRegex).downloadUrl
+
+ val patchesFile = kotlin.io.path.createTempFile().toFile().apply {
+ outputStream().use { URL(patchesDownloadUrl).openStream().copyTo(it) }
+ }
+
+ val patches = if (
+ signatureService.verify(
+ patchesFile,
+ signatureDownloadUrl,
+ configurationRepository.patches.publicKeyFile,
+ configurationRepository.patches.publicKeyId,
+ )
+ ) {
+ PatchBundleLoader.Jar(patchesFile)
+ } else {
+ // Use an empty set of patches if the signature is invalid.
+ emptySet()
+ }
+
+ patchesFile.delete()
+
+ ByteArrayOutputStream().use { stream ->
+ PatchUtils.Json.serialize(patches, outputStream = stream)
+
+ stream.toByteArray()
+ }
+ }
+ }
+ }
+
+ fun publicKeys(): APIAssetPublicKeys {
+ fun publicKeyBase64(getSignedAssetConfiguration: ConfigurationRepository.() -> ConfigurationRepository.SignedAssetConfiguration) =
+ configurationRepository.getSignedAssetConfiguration().publicKeyFile.readBytes().encodeBase64()
+
+ return APIAssetPublicKeys(
+ publicKeyBase64 { patches },
+ publicKeyBase64 { integrations },
+ )
+ }
+}
diff --git a/src/main/kotlin/app/revanced/api/configuration/services/SignatureService.kt b/src/main/kotlin/app/revanced/api/configuration/services/SignatureService.kt
new file mode 100644
index 00000000..80eb2d18
--- /dev/null
+++ b/src/main/kotlin/app/revanced/api/configuration/services/SignatureService.kt
@@ -0,0 +1,67 @@
+package app.revanced.api.configuration.services
+
+import com.github.benmanes.caffeine.cache.Caffeine
+import org.bouncycastle.openpgp.*
+import org.bouncycastle.openpgp.operator.bc.BcKeyFingerprintCalculator
+import org.bouncycastle.openpgp.operator.bc.BcPGPContentVerifierBuilderProvider
+import java.io.File
+import java.io.InputStream
+import java.net.URL
+import java.security.MessageDigest
+
+internal class SignatureService {
+ private val signatureCache = Caffeine
+ .newBuilder()
+ .maximumSize(2) // Assuming this is enough for patches and integrations.
+ .build() // Hash -> Verified.
+
+ fun verify(
+ file: File,
+ signatureDownloadUrl: String,
+ publicKeyFile: File,
+ publicKeyId: Long,
+ ): Boolean {
+ val fileBytes = file.readBytes()
+
+ return signatureCache.get(MessageDigest.getInstance("SHA-256").digest(fileBytes)) {
+ verify(
+ fileBytes = fileBytes,
+ signatureInputStream = URL(signatureDownloadUrl).openStream(),
+ publicKeyFileInputStream = publicKeyFile.inputStream(),
+ publicKeyId = publicKeyId,
+ )
+ }
+ }
+
+ private fun verify(
+ fileBytes: ByteArray,
+ signatureInputStream: InputStream,
+ publicKeyFileInputStream: InputStream,
+ publicKeyId: Long,
+ ) = getSignature(signatureInputStream).apply {
+ init(BcPGPContentVerifierBuilderProvider(), getPublicKey(publicKeyFileInputStream, publicKeyId))
+ update(fileBytes)
+ }.verify()
+
+ private fun getPublicKey(
+ publicKeyFileInputStream: InputStream,
+ publicKeyId: Long,
+ ): PGPPublicKey {
+ val decoderStream = PGPUtil.getDecoderStream(publicKeyFileInputStream)
+ val pgpPublicKeyRingCollection = PGPPublicKeyRingCollection(decoderStream, BcKeyFingerprintCalculator())
+ val publicKeyRing = pgpPublicKeyRingCollection.getPublicKeyRing(publicKeyId)
+ ?: throw IllegalArgumentException("Can't find public key ring with ID $publicKeyId.")
+
+ return publicKeyRing.getPublicKey(publicKeyId)
+ ?: throw IllegalArgumentException("Can't find public key with ID $publicKeyId.")
+ }
+
+ private fun getSignature(inputStream: InputStream): PGPSignature {
+ val decoderStream = PGPUtil.getDecoderStream(inputStream)
+ val pgpSignatureList = PGPObjectFactory(decoderStream, BcKeyFingerprintCalculator()).first {
+ it is PGPSignatureList
+ } as PGPSignatureList
+
+ return pgpSignatureList.first()
+ }
+}
diff --git a/src/main/resources/app/revanced/api/static/root/robots.txt b/src/main/resources/app/revanced/api/static/root/robots.txt
new file mode 100644
index 00000000..77470cb3
--- /dev/null
+++ b/src/main/resources/app/revanced/api/static/root/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /
\ No newline at end of file
diff --git a/src/main/resources/app/revanced/api/static/versioned/about.json b/src/main/resources/app/revanced/api/static/versioned/about.json
new file mode 100644
index 00000000..a947c48a
--- /dev/null
+++ b/src/main/resources/app/revanced/api/static/versioned/about.json
@@ -0,0 +1,83 @@
+{
+ "name": "ReVanced",
+ "about": "ReVanced was born out of Vanced's discontinuation and it is our goal to continue the legacy of what Vanced left behind. Thanks to ReVanced Patcher, it's possible to create long-lasting patches for nearly any Android app. ReVanced's patching system is designed to allow patches to work on new versions of the apps automatically with bare minimum maintenance.",
+ "branding": {
+ "logo": "https://raw.githubusercontent.com/ReVanced/revanced-branding/main/assets/revanced-logo/revanced-logo.svg"
+ },
+ "contact": {
+ "email": "contact@revanced.app"
+ },
+ "socials": [
+ {
+ "name": "Website",
+ "url": "https://revanced.app",
+ "preferred": true
+ },
+ {
+ "name": "GitHub",
+ "url": "https://github.com/revanced"
+ },
+ {
+ "name": "Twitter",
+ "url": "https://twitter.com/revancedapp"
+ },
+ {
+ "name": "Discord",
+ "url": "https://revanced.app/discord",
+ "preferred": true
+ },
+ {
+ "name": "Reddit",
+ "url": "https://www.reddit.com/r/revancedapp"
+ },
+ {
+ "name": "Telegram",
+ "url": "https://t.me/app_revanced"
+ },
+ {
+ "name": "YouTube",
+ "url": "https://www.youtube.com/@ReVanced"
+ }
+ ],
+ "donations": {
+ "wallets": [
+ {
+ "network": "Bitcoin",
+ "currency_code": "BTC",
+ "address": "bc1q4x8j6mt27y5gv0q625t8wkr87ruy8fprpy4v3f"
+ },
+ {
+ "network": "Dogecoin",
+ "currency_code": "DOGE",
+ "address": "D8GH73rNjudgi6bS2krrXWEsU9KShedLXp",
+ "preferred": true
+ },
+ {
+ "network": "Ethereum",
+ "currency_code": "ETH",
+ "address": "0x7ab4091e00363654bf84B34151225742cd92FCE5"
+ },
+ {
+ "network": "Litecoin",
+ "currency_code": "LTC",
+ "address": "LbJi8EuoDcwaZvykcKmcrM74jpjde23qJ2"
+ },
+ {
+ "network": "Monero",
+ "currency_code": "XMR",
+ "address": "46YwWDbZD6jVptuk5mLHsuAmh1BnUMSjSNYacozQQEraWSQ93nb2yYVRHoMR6PmFYWEHsLHg9tr1cH5M8Rtn7YaaGQPCjSh"
+ }
+ ],
+ "links": [
+ {
+ "name": "Open Collective",
+ "url": "https://opencollective.com/revanced",
+ "preferred": true
+ },
+ {
+ "name": "GitHub Sponsors",
+ "url": "https://github.com/sponsors/ReVanced"
+ }
+ ]
+ }
+}
diff --git a/src/main/resources/app/revanced/api/version.properties b/src/main/resources/app/revanced/api/version.properties
new file mode 100644
index 00000000..308c9f8e
--- /dev/null
+++ b/src/main/resources/app/revanced/api/version.properties
@@ -0,0 +1 @@
+version=${projectVersion}
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 00000000..6f0c78a3
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,10 @@
+
+
+
+ %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
diff --git a/static/img/favicon.ico b/static/img/favicon.ico
deleted file mode 100644
index 0a4ba620..00000000
Binary files a/static/img/favicon.ico and /dev/null differ