mirror of
https://github.com/yt-dlp/ejs.git
synced 2026-06-25 07:41:58 +00:00
Compare commits
26 Commits
0.2.0
...
7c5c5e0dd1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7c5c5e0dd1 | ||
|
|
2231f1fd6e | ||
|
|
aef78f70e7 | ||
|
|
4fb477f4af | ||
|
|
68448fa0ab | ||
|
|
cd4e87f52e | ||
|
|
41ff68e6f8 | ||
|
|
5bc9811c7a | ||
|
|
1b648c34c1 | ||
|
|
d13ca53401 | ||
|
|
a3095891a9 | ||
|
|
c51d14fa61 | ||
|
|
96c417f90a | ||
|
|
e91d03f58a | ||
|
|
32e63d577f | ||
|
|
83777e845d | ||
|
|
f4189efdc7 | ||
|
|
a0faf4144a | ||
|
|
06d71457ef | ||
|
|
3e76dde153 | ||
|
|
4f1d91dbb1 | ||
|
|
4b4ac2b896 | ||
|
|
2655b1f55f | ||
|
|
877164a326 | ||
|
|
25b77b7310 | ||
|
|
57fe708cf4 |
461
.github/workflows/ci.yml
vendored
461
.github/workflows/ci.yml
vendored
@@ -1,138 +1,250 @@
|
||||
name: CI
|
||||
on:
|
||||
push:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
branches: ['main']
|
||||
# This workflow contains required checks and needs to run for EVERY pull_request
|
||||
pull_request:
|
||||
paths-ignore:
|
||||
- 'README.md'
|
||||
- 'LICENSE'
|
||||
branches: ['**']
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
concurrency:
|
||||
group: ci-${{ github.event.pull_request.number || github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
ruff-format:
|
||||
name: Ruff format check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
args: "check --output-format github"
|
||||
env:
|
||||
ACTIONLINT_VERSION: "1.7.12"
|
||||
ACTIONLINT_SHA256SUM: 8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8
|
||||
ACTIONLINT_REPO: rhysd/actionlint
|
||||
GH_TELEMETRY: "false"
|
||||
|
||||
ruff-lint:
|
||||
name: Ruff linting check
|
||||
jobs:
|
||||
actionlint:
|
||||
name: Lint workflows
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: astral-sh/ruff-action@v3
|
||||
with:
|
||||
args: "format --check --diff"
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install requirements
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
ACTIONLINT_TARBALL: ${{ format('actionlint_{0}_linux_amd64.tar.gz', env.ACTIONLINT_VERSION) }}
|
||||
shell: bash
|
||||
run: |
|
||||
sudo apt -y install shellcheck
|
||||
gh release download \
|
||||
--repo "${ACTIONLINT_REPO}" \
|
||||
--pattern "${ACTIONLINT_TARBALL}" \
|
||||
"v${ACTIONLINT_VERSION}"
|
||||
gh attestation verify \
|
||||
--repo "${ACTIONLINT_REPO}" \
|
||||
"${ACTIONLINT_TARBALL}"
|
||||
printf '%s %s' "${ACTIONLINT_SHA256SUM}" "${ACTIONLINT_TARBALL}" | sha256sum -c -
|
||||
tar xvzf "${ACTIONLINT_TARBALL}" actionlint
|
||||
sudo install -D --mode=755 actionlint /usr/bin/
|
||||
|
||||
- name: Run actionlint
|
||||
run: |
|
||||
actionlint -color
|
||||
|
||||
zizmor:
|
||||
name: Audit workflows
|
||||
permissions:
|
||||
contents: read
|
||||
actions: read # Needed by zizmorcore/zizmor-action if repository is private
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Run zizmor
|
||||
uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2
|
||||
with:
|
||||
advanced-security: false
|
||||
persona: pedantic
|
||||
|
||||
ruff_format:
|
||||
name: Ruff format check
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: astral-sh/ruff-action@4919ec5cf1f49eff0871dbcea0da843445b837e6 # v3.6.1
|
||||
with:
|
||||
args: "check --output-format github"
|
||||
|
||||
ruff_lint:
|
||||
name: Ruff linting check
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: astral-sh/ruff-action@4919ec5cf1f49eff0871dbcea0da843445b837e6 # v3.6.1
|
||||
with:
|
||||
args: "format --check --diff"
|
||||
|
||||
prettier:
|
||||
name: Prettier check
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
deno install --frozen
|
||||
|
||||
- name: Run Prettier check
|
||||
run: |
|
||||
deno task fmt:check
|
||||
|
||||
eslint:
|
||||
name: ESLint check
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
deno install --frozen
|
||||
|
||||
- name: Run ESLint check
|
||||
run: |
|
||||
deno task lint
|
||||
|
||||
python_tests:
|
||||
name: Python tests
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
runner: [ubuntu-latest, windows-latest]
|
||||
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14', pypy-3.11]
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# required for hatch-vcs versioning
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@v6
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Build project
|
||||
shell: bash
|
||||
run: |
|
||||
# `pip install -e` omits the force-included JS, so use `build` instead
|
||||
python -m pip install -U build
|
||||
python -m build
|
||||
|
||||
- name: Unpack wheel (Linux)
|
||||
if: matrix.runner == 'ubuntu-latest'
|
||||
shell: bash
|
||||
run: |
|
||||
unzip -u dist/yt_dlp_ejs-*.whl "yt_dlp_ejs/*"
|
||||
|
||||
- name: Unpack wheel (Windows)
|
||||
if: matrix.runner == 'windows-latest'
|
||||
shell: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = "Stop"
|
||||
$PSNativeCommandUseErrorActionPreference = $true
|
||||
Expand-Archive -Path dist/yt_dlp_ejs-*.whl -DestinationPath ./ -Force
|
||||
|
||||
- name: Run Python tests
|
||||
timeout-minutes: 5
|
||||
shell: bash
|
||||
run: |
|
||||
python -Werror -m unittest
|
||||
|
||||
prepare:
|
||||
name: Prepare JS runtime tests
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno v2.x (latest)
|
||||
uses: denoland/setup-deno@v2
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
deno-version: v2.x
|
||||
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
deno install --frozen
|
||||
|
||||
- name: Build control bundle
|
||||
run: |
|
||||
deno task bundle
|
||||
|
||||
- name: Generate bundle hashes
|
||||
shell: bash
|
||||
run: |
|
||||
pushd dist
|
||||
sha256sum -- yt.solver.*.js | tee SHA2-256SUMS
|
||||
popd
|
||||
|
||||
- name: Upload bundle hashes
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: bundle-hashes
|
||||
path: |
|
||||
dist/SHA2-256SUMS
|
||||
compression-level: 0
|
||||
|
||||
- name: Cache player JS files
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
|
||||
env:
|
||||
SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1
|
||||
with:
|
||||
path: |
|
||||
src/yt/solver/test/players
|
||||
key: test-player-js-${{ hashFiles('src/yt/solver/test/tests.ts') }}
|
||||
|
||||
- name: Download player JS files
|
||||
timeout-minutes: 15
|
||||
run: |
|
||||
deno run \
|
||||
--no-prompt \
|
||||
@@ -141,52 +253,146 @@ jobs:
|
||||
--allow-net=www.youtube.com \
|
||||
--allow-sys=uid \
|
||||
src/yt/solver/test/download.ts
|
||||
|
||||
- name: Upload player JS artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: player-js
|
||||
path: |
|
||||
src/yt/solver/test/players/*
|
||||
compression-level: 0
|
||||
|
||||
deno_build:
|
||||
name: Test Deno build
|
||||
pnpm_build:
|
||||
name: Test pnpm build
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# required for hatch-vcs versioning
|
||||
fetch-depth: 0
|
||||
- name: Install Deno
|
||||
uses: denoland/setup-deno@v2
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install pnpm
|
||||
uses: pnpm/action-setup@fc06bc1257f339d1d5d8b3a19a8cae5388b55320 # v5.0.0
|
||||
with:
|
||||
deno-version: "2.0.0" # minimum supported version
|
||||
- uses: actions/setup-python@v6
|
||||
version: 10
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: "3.10" # minimum supported version
|
||||
# minimum supported version
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m pip install -U build
|
||||
- name: Test Deno build
|
||||
|
||||
- name: Test pnpm build
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Verify artifact contents
|
||||
shell: bash
|
||||
run: |
|
||||
tar -tvzf dist/yt_dlp_ejs-*.tar.gz
|
||||
unzip -l dist/yt_dlp_ejs-*.whl | tee .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/core\.min\.js' .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
- name: Install Deno requirements
|
||||
|
||||
- name: Install pnpm requirements
|
||||
run: |
|
||||
deno install
|
||||
- name: Bundle with Deno
|
||||
pnpm install --frozen-lockfile
|
||||
|
||||
- name: Bundle with pnpm
|
||||
run: |
|
||||
deno task bundle
|
||||
pnpm run bundle
|
||||
|
||||
- name: Download bundle hashes
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
name: bundle-hashes
|
||||
|
||||
- name: Verify bundle hashes
|
||||
run: |
|
||||
cd dist
|
||||
sha256sum -c SHA2-256SUMS
|
||||
|
||||
deno_lock_check:
|
||||
name: Test Deno lockfile
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
# minimum supported version
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Verify lockfile
|
||||
run: |
|
||||
python ./check.py
|
||||
|
||||
deno_build:
|
||||
name: Test Deno build
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# required for hatch-vcs versioning
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
# minimum supported version
|
||||
deno-version: "2.0.0"
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
# minimum supported version
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m pip install -U build
|
||||
|
||||
- name: Test Deno build
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Verify artifact contents
|
||||
shell: bash
|
||||
run: |
|
||||
tar -tvzf dist/yt_dlp_ejs-*.tar.gz
|
||||
unzip -l dist/yt_dlp_ejs-*.whl | tee .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/core\.min\.js' .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install --frozen
|
||||
|
||||
- name: Bundle with Deno
|
||||
run: |
|
||||
deno task bundle
|
||||
|
||||
- name: Download bundle hashes
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
name: bundle-hashes
|
||||
|
||||
- name: Verify bundle hashes
|
||||
run: |
|
||||
cd dist
|
||||
@@ -195,65 +401,93 @@ jobs:
|
||||
deno_tests:
|
||||
name: Run Deno tests
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Deno
|
||||
uses: denoland/setup-deno@v2
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
deno-version: "2.0.0" # minimum supported version
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Deno
|
||||
uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
# minimum supported version
|
||||
deno-version: "2.0.0"
|
||||
|
||||
- name: Install Deno requirements
|
||||
run: |
|
||||
deno install
|
||||
deno install --frozen
|
||||
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: src/yt/solver/test/players
|
||||
name: player-js
|
||||
|
||||
- name: Run Deno tests
|
||||
run: |
|
||||
deno test \
|
||||
xargs -n 1 -P 10 deno test \
|
||||
--no-prompt \
|
||||
--allow-read=src/yt/solver/test/players/
|
||||
--no-check \
|
||||
--allow-read=src/yt/solver/test/players/ \
|
||||
--filter <<<"$(printf -- '-%s-\n' main tcc tce es5 es6 tv tv_es6 phone es6_tcc es6_tce)"
|
||||
|
||||
bun_build:
|
||||
name: Test Bun build
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# required for hatch-vcs versioning
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
with:
|
||||
bun-version: "1.0.31" # minimum supported version
|
||||
- uses: actions/setup-python@v6
|
||||
# minimum supported version
|
||||
bun-version: "1.0.31"
|
||||
no-cache: true
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: "3.10" # minimum supported version
|
||||
# minimum supported version
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m pip install -U build
|
||||
|
||||
- name: Test Bun build
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Verify artifact contents
|
||||
shell: bash
|
||||
run: |
|
||||
tar -tvzf dist/yt_dlp_ejs-*.tar.gz
|
||||
unzip -l dist/yt_dlp_ejs-*.whl | tee .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/core\.min\.js' .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
|
||||
- name: Install Bun requirements
|
||||
run: |
|
||||
bun install
|
||||
bun install --frozen-lockfile
|
||||
|
||||
- name: Bundle with Bun
|
||||
run: |
|
||||
bun --bun run bundle
|
||||
|
||||
- name: Download bundle hashes
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
name: bundle-hashes
|
||||
|
||||
- name: Verify bundle hashes
|
||||
run: |
|
||||
cd dist
|
||||
@@ -262,21 +496,31 @@ jobs:
|
||||
bun_tests:
|
||||
name: Run Bun tests
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@v2
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
bun-version: "1.2.11" # XXX: We support 1.0.31, but test suite requires 1.2.11+
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Bun
|
||||
uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6 # v2.2.0
|
||||
with:
|
||||
# XXX: We support 1.0.31, but test suite requires 1.2.11+
|
||||
bun-version: "1.2.11"
|
||||
no-cache: true
|
||||
|
||||
- name: Install Bun requirements
|
||||
run: |
|
||||
bun install
|
||||
bun install --frozen-lockfile
|
||||
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: src/yt/solver/test/players
|
||||
name: player-js
|
||||
|
||||
- name: Run Bun tests
|
||||
run: |
|
||||
bun test
|
||||
@@ -284,41 +528,57 @@ jobs:
|
||||
node_build:
|
||||
name: Test Node build
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
# required for hatch-vcs versioning
|
||||
fetch-depth: 0
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v6
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
node-version: "20.0" # minimum supported version
|
||||
- uses: actions/setup-python@v6
|
||||
# minimum supported version
|
||||
node-version: "20.0"
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: "3.10" # minimum supported version
|
||||
# minimum supported version
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m pip install -U build
|
||||
|
||||
- name: Test Node build
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Verify artifact contents
|
||||
shell: bash
|
||||
run: |
|
||||
tar -tvzf dist/yt_dlp_ejs-*.tar.gz
|
||||
unzip -l dist/yt_dlp_ejs-*.whl | tee .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/core\.min\.js' .wheel_contents
|
||||
grep -q 'yt_dlp_ejs/yt/solver/lib\.min\.js' .wheel_contents
|
||||
|
||||
- name: Install Node requirements
|
||||
run: |
|
||||
npm install
|
||||
npm ci
|
||||
|
||||
- name: Bundle with Node
|
||||
run: |
|
||||
npm run bundle
|
||||
|
||||
- name: Download bundle hashes
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
name: bundle-hashes
|
||||
|
||||
- name: Verify bundle hashes
|
||||
run: |
|
||||
cd dist
|
||||
@@ -327,39 +587,54 @@ jobs:
|
||||
node_tests:
|
||||
name: Run Node tests
|
||||
needs: [prepare]
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@v6
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
node-version: "22.18" # XXX: We support 20.0, but test suite requires 22.18+
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install Node
|
||||
uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
|
||||
with:
|
||||
# XXX: We support 20.0, but test suite requires 22.18+
|
||||
node-version: "22.18"
|
||||
|
||||
- name: Install Node requirements
|
||||
run: |
|
||||
npm install
|
||||
npm ci
|
||||
|
||||
- name: Download player JS artifact
|
||||
uses: actions/download-artifact@v5
|
||||
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: src/yt/solver/test/players
|
||||
name: player-js
|
||||
|
||||
- name: Run Node tests
|
||||
run: |
|
||||
node --test
|
||||
|
||||
all_passed:
|
||||
# Required check; do not change name
|
||||
name: all_passed
|
||||
needs:
|
||||
- ruff-format
|
||||
- ruff-lint
|
||||
- actionlint
|
||||
- zizmor
|
||||
- ruff_format
|
||||
- ruff_lint
|
||||
- prettier
|
||||
- eslint
|
||||
- python_tests
|
||||
- pnpm_build
|
||||
- deno_lock_check
|
||||
- deno_build
|
||||
- deno_tests
|
||||
- bun_build
|
||||
- bun_tests
|
||||
- node_build
|
||||
- node_tests
|
||||
runs-on: ubuntu-latest
|
||||
runs-on: ubuntu-slim
|
||||
steps:
|
||||
- name: All checks passed
|
||||
run: |
|
||||
echo "All checks passed!"
|
||||
- run: |
|
||||
true
|
||||
|
||||
55
.github/workflows/release.yml
vendored
55
.github/workflows/release.yml
vendored
@@ -4,43 +4,56 @@ on:
|
||||
tags:
|
||||
- "*"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
permissions: {}
|
||||
|
||||
env:
|
||||
GH_TELEMETRY: "false"
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build artifacts
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: denoland/setup-deno@v2
|
||||
fetch-depth: 0 # Needed for hatch-vcs versioning
|
||||
persist-credentials: false
|
||||
|
||||
- uses: denoland/setup-deno@e95548e56dfa95d4e1a28d6f422fafe75c4c26fb # v2.0.3
|
||||
with:
|
||||
deno-version: v2.x
|
||||
- uses: actions/setup-python@v6
|
||||
deno-version: 3fbb1daddbc9333cddf0d8c0735811717dd70f7a # v2.6.3
|
||||
cache: false
|
||||
|
||||
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
|
||||
- name: Install Python requirements
|
||||
run: |
|
||||
python -m pip install -U build
|
||||
|
||||
- name: Build Python artifacts
|
||||
run: |
|
||||
python -m build
|
||||
|
||||
- name: Upload Python artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: artifacts-py
|
||||
path: |
|
||||
dist/yt_dlp_ejs-*.whl
|
||||
dist/yt_dlp_ejs-*.tar.gz
|
||||
compression-level: 0
|
||||
|
||||
- name: Build JavaScript artifacts
|
||||
run: |
|
||||
deno install
|
||||
deno install --frozen
|
||||
deno task bundle
|
||||
|
||||
- name: Upload JavaScript artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
|
||||
with:
|
||||
name: artifacts-js
|
||||
path: |
|
||||
@@ -51,17 +64,17 @@ jobs:
|
||||
name: Publish to PyPI
|
||||
needs: [build]
|
||||
if: github.repository == 'yt-dlp/ejs'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write # required for PyPI trusted publishing
|
||||
id-token: write # Needed for PyPI trusted publishing
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/download-artifact@v5
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
name: artifacts-py
|
||||
|
||||
- name: Publish to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
||||
with:
|
||||
verbose: true
|
||||
|
||||
@@ -69,18 +82,20 @@ jobs:
|
||||
name: Create GitHub release
|
||||
needs: [build, publish_pypi]
|
||||
if: always() && !failure() && !cancelled()
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
contents: write # Needed by gh to publish release to Github
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v5
|
||||
persist-credentials: false
|
||||
|
||||
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
||||
with:
|
||||
path: dist
|
||||
pattern: artifacts-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Create GitHub Release
|
||||
env:
|
||||
TAG: ${{ github.ref_name }}
|
||||
|
||||
8
.github/zizmor.yml
vendored
Normal file
8
.github/zizmor.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
rules:
|
||||
concurrency-limits:
|
||||
ignore:
|
||||
- release.yml # Can only be triggered by a tag pushed by a maintainer
|
||||
unpinned-uses:
|
||||
config:
|
||||
policies:
|
||||
"*": hash-pin
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,8 +2,5 @@
|
||||
*.py[cd]
|
||||
/yt_dlp_ejs/_version.py
|
||||
/node_modules
|
||||
/bun.lock
|
||||
/deno.lock
|
||||
/package-lock.json
|
||||
/.idea
|
||||
/.venv
|
||||
|
||||
67
README.md
67
README.md
@@ -12,9 +12,11 @@ pip install -U yt-dlp-ejs
|
||||
|
||||
## Development
|
||||
|
||||
While this project does pin its dependencies,
|
||||
it does not use lockfiles or enforce a particular package manager.
|
||||
You may install dependencies using any compatible package manager.
|
||||
The project provides lockfiles for every supported package manager.
|
||||
|
||||
If you only have Python and a JS runtime, then you may instead run `./hatch_build.py`.
|
||||
This will transparently invoke one of the supported JS runtimes for the build.
|
||||
|
||||
If you notice differences between different runtimes' builds
|
||||
please open an issue [here](<https://github.com/yt-dlp/ejs/issues/new>).
|
||||
|
||||
@@ -26,34 +28,37 @@ The build hook will automatically invoke `deno`, `bun` or `node` as required.
|
||||
Alternatively, to only build the JavaScript files you can run the `bundle` script manually:
|
||||
|
||||
```bash
|
||||
# Deno:
|
||||
deno install
|
||||
deno task bundle
|
||||
|
||||
# Bun:
|
||||
bun install
|
||||
bun --bun run bundle
|
||||
|
||||
# Node:
|
||||
npm install
|
||||
npm run bundle
|
||||
python hatch_build.py
|
||||
```
|
||||
|
||||
This will automatically select an available runtime and build using it.
|
||||
|
||||
For more fine-grained control over how to build the package, you can set these environment variables:
|
||||
- `EJS_BUILD_SKIP_INSTALL`: If this environment variable is set, the install step will be skipped.
|
||||
It is expected that the required packages are available for the selected bundler.
|
||||
No network access should be required if this variable is set.
|
||||
- `EJS_BUILD_INSTALLER`: Order of installers to try, separated by `:` on POSIX or `;` on Windows.
|
||||
These will be used to install the required dependencies for bundling the JavaScript package.
|
||||
Can be any of `pnpm`, `deno`, `bun` or `npm` (this is also the default order).
|
||||
- `EJS_BUILD_BUNDLER`: Order of bundlers to try, separated by `:` on POSIX or `;` on Windows.
|
||||
These will be used to perform the bundling of the JavaScript package (calling rollup under the hood).
|
||||
Can be any of `esbuild`, `pnpm`, `deno`, `bun`, `node` (this is also the default order).
|
||||
|
||||
### Tests
|
||||
|
||||
First, make sure the project's dependencies are installed and download the player JS files:
|
||||
|
||||
```bash
|
||||
# Deno:
|
||||
deno install
|
||||
deno install --frozen
|
||||
deno run src/yt/solver/test/download.ts
|
||||
|
||||
# Bun:
|
||||
bun install
|
||||
bun install --frozen-lockfile
|
||||
bun --bun run src/yt/solver/test/download.ts
|
||||
|
||||
# Node 22.6+:
|
||||
npm install
|
||||
npm ci
|
||||
node --experimental-strip-types src/yt/solver/test/download.ts
|
||||
```
|
||||
|
||||
@@ -70,10 +75,36 @@ bun test
|
||||
node --test
|
||||
```
|
||||
|
||||
## Upgrading packages
|
||||
|
||||
When upgrading packages in package.json, all lockfiles must be updated simultaneously.
|
||||
To do this, run the following commands:
|
||||
|
||||
```bash
|
||||
# Upgrade packages automatically (or manually adjust versions)
|
||||
pnpm upgrade --latest
|
||||
|
||||
# Generate base `package-lock.json`
|
||||
rm -rf node_modules
|
||||
npm install
|
||||
|
||||
# Migrate to other package managers
|
||||
pnpm import
|
||||
bun pm migrate --force
|
||||
|
||||
# Make sure to use a deno with lockfile v4 (<2.3)
|
||||
deno install --lockfile-only
|
||||
|
||||
# Ensure that `deno.json` is the same as `package-lock.json`.
|
||||
# Note: you may need to manually update the `ADDITIONAL_PACKAGES_NODE`
|
||||
# and/or `ADDITIONAL_PACKAGES_DENO` variables in `./check.py`.
|
||||
python check.py
|
||||
```
|
||||
|
||||
## Licensing
|
||||
|
||||
This code is licensed under [Unlicense](<https://unlicense.org/>).
|
||||
|
||||
An exception to this are the prebuilt wheels, which contain both
|
||||
An exception to this is the prebuilt wheels, which contain both
|
||||
[`meriyah`](<https://github.com/meriyah/meriyah>) and [`astring`](<https://github.com/davidbonnet/astring>),
|
||||
licensed under [`ISC`](<https://github.com/meriyah/meriyah?tab=ISC-1-ov-file>) and [`MIT`](<https://github.com/davidbonnet/astring?tab=MIT-1-ov-file>), respectively.
|
||||
|
||||
32
build.mjs
Normal file
32
build.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
import * as esbuild from "esbuild";
|
||||
|
||||
const buildConfig = await stdinJSON();
|
||||
const result = await esbuild.build(buildConfig);
|
||||
console.log(JSON.stringify(result.metafile ?? null));
|
||||
await esbuild.stop();
|
||||
|
||||
async function stdinJSON() {
|
||||
const chunks = [];
|
||||
if (globalThis.Deno) {
|
||||
for await (const chunk of globalThis.Deno.stdin.readable) {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
const length = chunks.reduce(
|
||||
(previous, chunk) => previous + chunk.length,
|
||||
0,
|
||||
);
|
||||
const buffer = new Uint8Array(length);
|
||||
let offset = 0;
|
||||
for (const chunk of chunks) {
|
||||
buffer.set(chunk, offset);
|
||||
offset += chunk.length;
|
||||
}
|
||||
return JSON.parse(new TextDecoder().decode(buffer));
|
||||
}
|
||||
|
||||
for await (const chunk of process.stdin) {
|
||||
chunks.push(chunk);
|
||||
}
|
||||
const text = Buffer.concat(chunks).toString("utf-8");
|
||||
return JSON.parse(text);
|
||||
}
|
||||
343
bun.lock
Normal file
343
bun.lock
Normal file
@@ -0,0 +1,343 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 1,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "ejs",
|
||||
"dependencies": {
|
||||
"astring": "1.9.0",
|
||||
"meriyah": "6.1.4",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.38.0",
|
||||
"@types/bun": "1.3.0",
|
||||
"@types/deno": "2.5.0",
|
||||
"@types/node": "24.8.1",
|
||||
"esbuild": "0.28.0",
|
||||
"eslint": "9.38.0",
|
||||
"globals": "16.4.0",
|
||||
"prettier": "3.6.2",
|
||||
"typescript-eslint": "8.46.2",
|
||||
},
|
||||
},
|
||||
},
|
||||
"packages": {
|
||||
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.28.0", "", { "os": "aix", "cpu": "ppc64" }, "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA=="],
|
||||
|
||||
"@esbuild/android-arm": ["@esbuild/android-arm@0.28.0", "", { "os": "android", "cpu": "arm" }, "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ=="],
|
||||
|
||||
"@esbuild/android-arm64": ["@esbuild/android-arm64@0.28.0", "", { "os": "android", "cpu": "arm64" }, "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw=="],
|
||||
|
||||
"@esbuild/android-x64": ["@esbuild/android-x64@0.28.0", "", { "os": "android", "cpu": "x64" }, "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA=="],
|
||||
|
||||
"@esbuild/darwin-arm64": ["@esbuild/darwin-arm64@0.28.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q=="],
|
||||
|
||||
"@esbuild/darwin-x64": ["@esbuild/darwin-x64@0.28.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ=="],
|
||||
|
||||
"@esbuild/freebsd-arm64": ["@esbuild/freebsd-arm64@0.28.0", "", { "os": "freebsd", "cpu": "arm64" }, "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q=="],
|
||||
|
||||
"@esbuild/freebsd-x64": ["@esbuild/freebsd-x64@0.28.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw=="],
|
||||
|
||||
"@esbuild/linux-arm": ["@esbuild/linux-arm@0.28.0", "", { "os": "linux", "cpu": "arm" }, "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw=="],
|
||||
|
||||
"@esbuild/linux-arm64": ["@esbuild/linux-arm64@0.28.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A=="],
|
||||
|
||||
"@esbuild/linux-ia32": ["@esbuild/linux-ia32@0.28.0", "", { "os": "linux", "cpu": "ia32" }, "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ=="],
|
||||
|
||||
"@esbuild/linux-loong64": ["@esbuild/linux-loong64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg=="],
|
||||
|
||||
"@esbuild/linux-mips64el": ["@esbuild/linux-mips64el@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w=="],
|
||||
|
||||
"@esbuild/linux-ppc64": ["@esbuild/linux-ppc64@0.28.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg=="],
|
||||
|
||||
"@esbuild/linux-riscv64": ["@esbuild/linux-riscv64@0.28.0", "", { "os": "linux", "cpu": "none" }, "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ=="],
|
||||
|
||||
"@esbuild/linux-s390x": ["@esbuild/linux-s390x@0.28.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q=="],
|
||||
|
||||
"@esbuild/linux-x64": ["@esbuild/linux-x64@0.28.0", "", { "os": "linux", "cpu": "x64" }, "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ=="],
|
||||
|
||||
"@esbuild/netbsd-arm64": ["@esbuild/netbsd-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw=="],
|
||||
|
||||
"@esbuild/netbsd-x64": ["@esbuild/netbsd-x64@0.28.0", "", { "os": "none", "cpu": "x64" }, "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw=="],
|
||||
|
||||
"@esbuild/openbsd-arm64": ["@esbuild/openbsd-arm64@0.28.0", "", { "os": "openbsd", "cpu": "arm64" }, "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g=="],
|
||||
|
||||
"@esbuild/openbsd-x64": ["@esbuild/openbsd-x64@0.28.0", "", { "os": "openbsd", "cpu": "x64" }, "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA=="],
|
||||
|
||||
"@esbuild/openharmony-arm64": ["@esbuild/openharmony-arm64@0.28.0", "", { "os": "none", "cpu": "arm64" }, "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w=="],
|
||||
|
||||
"@esbuild/sunos-x64": ["@esbuild/sunos-x64@0.28.0", "", { "os": "sunos", "cpu": "x64" }, "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw=="],
|
||||
|
||||
"@esbuild/win32-arm64": ["@esbuild/win32-arm64@0.28.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA=="],
|
||||
|
||||
"@esbuild/win32-ia32": ["@esbuild/win32-ia32@0.28.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA=="],
|
||||
|
||||
"@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.0", "", { "os": "win32", "cpu": "x64" }, "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw=="],
|
||||
|
||||
"@eslint-community/eslint-utils": ["@eslint-community/eslint-utils@4.9.0", "", { "dependencies": { "eslint-visitor-keys": "^3.4.3" }, "peerDependencies": { "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" } }, "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g=="],
|
||||
|
||||
"@eslint-community/regexpp": ["@eslint-community/regexpp@4.12.2", "", {}, "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="],
|
||||
|
||||
"@eslint/config-array": ["@eslint/config-array@0.21.1", "", { "dependencies": { "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", "minimatch": "^3.1.2" } }, "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA=="],
|
||||
|
||||
"@eslint/config-helpers": ["@eslint/config-helpers@0.4.2", "", { "dependencies": { "@eslint/core": "^0.17.0" } }, "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw=="],
|
||||
|
||||
"@eslint/core": ["@eslint/core@0.16.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q=="],
|
||||
|
||||
"@eslint/eslintrc": ["@eslint/eslintrc@3.3.3", "", { "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.1", "minimatch": "^3.1.2", "strip-json-comments": "^3.1.1" } }, "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ=="],
|
||||
|
||||
"@eslint/js": ["@eslint/js@9.38.0", "", {}, "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A=="],
|
||||
|
||||
"@eslint/object-schema": ["@eslint/object-schema@2.1.7", "", {}, "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="],
|
||||
|
||||
"@eslint/plugin-kit": ["@eslint/plugin-kit@0.4.1", "", { "dependencies": { "@eslint/core": "^0.17.0", "levn": "^0.4.1" } }, "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA=="],
|
||||
|
||||
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
|
||||
|
||||
"@humanfs/node": ["@humanfs/node@0.16.7", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.4.0" } }, "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ=="],
|
||||
|
||||
"@humanwhocodes/module-importer": ["@humanwhocodes/module-importer@1.0.1", "", {}, "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="],
|
||||
|
||||
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
|
||||
|
||||
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
||||
|
||||
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
||||
|
||||
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
||||
|
||||
"@types/bun": ["@types/bun@1.3.0", "", { "dependencies": { "bun-types": "1.3.0" } }, "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA=="],
|
||||
|
||||
"@types/deno": ["@types/deno@2.5.0", "", {}, "sha512-g8JS38vmc0S87jKsFzre+0ZyMOUDHPVokEJymSCRlL57h6f/FdKPWBXgdFh3Z8Ees9sz11qt9VWELU9Y9ZkiVw=="],
|
||||
|
||||
"@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@24.8.1", "", { "dependencies": { "undici-types": "~7.14.0" } }, "sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.7", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin": ["@typescript-eslint/eslint-plugin@8.46.2", "", { "dependencies": { "@eslint-community/regexpp": "^4.10.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/type-utils": "8.46.2", "@typescript-eslint/utils": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "graphemer": "^1.4.0", "ignore": "^7.0.0", "natural-compare": "^1.4.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "@typescript-eslint/parser": "^8.46.2", "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w=="],
|
||||
|
||||
"@typescript-eslint/parser": ["@typescript-eslint/parser@8.46.2", "", { "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g=="],
|
||||
|
||||
"@typescript-eslint/project-service": ["@typescript-eslint/project-service@8.46.2", "", { "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.46.2", "@typescript-eslint/types": "^8.46.2", "debug": "^4.3.4" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg=="],
|
||||
|
||||
"@typescript-eslint/scope-manager": ["@typescript-eslint/scope-manager@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2" } }, "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA=="],
|
||||
|
||||
"@typescript-eslint/tsconfig-utils": ["@typescript-eslint/tsconfig-utils@8.46.2", "", { "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag=="],
|
||||
|
||||
"@typescript-eslint/type-utils": ["@typescript-eslint/type-utils@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2", "debug": "^4.3.4", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA=="],
|
||||
|
||||
"@typescript-eslint/types": ["@typescript-eslint/types@8.46.2", "", {}, "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree": ["@typescript-eslint/typescript-estree@8.46.2", "", { "dependencies": { "@typescript-eslint/project-service": "8.46.2", "@typescript-eslint/tsconfig-utils": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/visitor-keys": "8.46.2", "debug": "^4.3.4", "fast-glob": "^3.3.2", "is-glob": "^4.0.3", "minimatch": "^9.0.4", "semver": "^7.6.0", "ts-api-utils": "^2.1.0" }, "peerDependencies": { "typescript": ">=4.8.4 <6.0.0" } }, "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ=="],
|
||||
|
||||
"@typescript-eslint/utils": ["@typescript-eslint/utils@8.46.2", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.7.0", "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg=="],
|
||||
|
||||
"@typescript-eslint/visitor-keys": ["@typescript-eslint/visitor-keys@8.46.2", "", { "dependencies": { "@typescript-eslint/types": "8.46.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w=="],
|
||||
|
||||
"acorn": ["acorn@8.15.0", "", { "bin": "bin/acorn" }, "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="],
|
||||
|
||||
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
|
||||
|
||||
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
|
||||
|
||||
"astring": ["astring@1.9.0", "", { "bin": "bin/astring" }, "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="],
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
||||
|
||||
"bun-types": ["bun-types@1.3.0", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ=="],
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
|
||||
|
||||
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
|
||||
|
||||
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
|
||||
|
||||
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
||||
|
||||
"csstype": ["csstype@3.2.3", "", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||
|
||||
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||
|
||||
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
|
||||
|
||||
"esbuild": ["esbuild@0.28.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.28.0", "@esbuild/android-arm": "0.28.0", "@esbuild/android-arm64": "0.28.0", "@esbuild/android-x64": "0.28.0", "@esbuild/darwin-arm64": "0.28.0", "@esbuild/darwin-x64": "0.28.0", "@esbuild/freebsd-arm64": "0.28.0", "@esbuild/freebsd-x64": "0.28.0", "@esbuild/linux-arm": "0.28.0", "@esbuild/linux-arm64": "0.28.0", "@esbuild/linux-ia32": "0.28.0", "@esbuild/linux-loong64": "0.28.0", "@esbuild/linux-mips64el": "0.28.0", "@esbuild/linux-ppc64": "0.28.0", "@esbuild/linux-riscv64": "0.28.0", "@esbuild/linux-s390x": "0.28.0", "@esbuild/linux-x64": "0.28.0", "@esbuild/netbsd-arm64": "0.28.0", "@esbuild/netbsd-x64": "0.28.0", "@esbuild/openbsd-arm64": "0.28.0", "@esbuild/openbsd-x64": "0.28.0", "@esbuild/openharmony-arm64": "0.28.0", "@esbuild/sunos-x64": "0.28.0", "@esbuild/win32-arm64": "0.28.0", "@esbuild/win32-ia32": "0.28.0", "@esbuild/win32-x64": "0.28.0" }, "bin": "bin/esbuild" }, "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw=="],
|
||||
|
||||
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
|
||||
|
||||
"eslint": ["eslint@9.38.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.21.1", "@eslint/config-helpers": "^0.4.1", "@eslint/core": "^0.16.0", "@eslint/eslintrc": "^3.3.1", "@eslint/js": "9.38.0", "@eslint/plugin-kit": "^0.4.0", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.4.0", "eslint-visitor-keys": "^4.2.1", "espree": "^10.4.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": "bin/eslint.js" }, "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw=="],
|
||||
|
||||
"eslint-scope": ["eslint-scope@8.4.0", "", { "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" } }, "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg=="],
|
||||
|
||||
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.1", "", {}, "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="],
|
||||
|
||||
"espree": ["espree@10.4.0", "", { "dependencies": { "acorn": "^8.15.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.1" } }, "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ=="],
|
||||
|
||||
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
|
||||
|
||||
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
|
||||
|
||||
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
|
||||
|
||||
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-glob": ["fast-glob@3.3.3", "", { "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.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
|
||||
"fast-levenshtein": ["fast-levenshtein@2.0.6", "", {}, "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="],
|
||||
|
||||
"fastq": ["fastq@1.19.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ=="],
|
||||
|
||||
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
|
||||
|
||||
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
||||
|
||||
"find-up": ["find-up@5.0.0", "", { "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" } }, "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng=="],
|
||||
|
||||
"flat-cache": ["flat-cache@4.0.1", "", { "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.4" } }, "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw=="],
|
||||
|
||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||
|
||||
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
|
||||
|
||||
"globals": ["globals@16.4.0", "", {}, "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="],
|
||||
|
||||
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
|
||||
|
||||
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
|
||||
|
||||
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
|
||||
|
||||
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
|
||||
|
||||
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
|
||||
|
||||
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
||||
|
||||
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
||||
|
||||
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
||||
|
||||
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
||||
|
||||
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": "bin/js-yaml.js" }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
|
||||
|
||||
"json-buffer": ["json-buffer@3.0.1", "", {}, "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="],
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-stable-stringify-without-jsonify": ["json-stable-stringify-without-jsonify@1.0.1", "", {}, "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="],
|
||||
|
||||
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
|
||||
|
||||
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
|
||||
|
||||
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
||||
|
||||
"meriyah": ["meriyah@6.1.4", "", {}, "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ=="],
|
||||
|
||||
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
|
||||
|
||||
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
|
||||
|
||||
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
|
||||
|
||||
"p-locate": ["p-locate@5.0.0", "", { "dependencies": { "p-limit": "^3.0.2" } }, "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw=="],
|
||||
|
||||
"parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="],
|
||||
|
||||
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
|
||||
|
||||
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
||||
|
||||
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.6.2", "", { "bin": "bin/prettier.cjs" }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
|
||||
|
||||
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
|
||||
|
||||
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
||||
|
||||
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
|
||||
|
||||
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
||||
|
||||
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
||||
|
||||
"semver": ["semver@7.7.3", "", { "bin": "bin/semver.js" }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
|
||||
|
||||
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
|
||||
|
||||
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
|
||||
|
||||
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
||||
|
||||
"ts-api-utils": ["ts-api-utils@2.1.0", "", { "peerDependencies": { "typescript": ">=4.8.4" } }, "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ=="],
|
||||
|
||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||
|
||||
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||
|
||||
"typescript-eslint": ["typescript-eslint@8.46.2", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.46.2", "@typescript-eslint/parser": "8.46.2", "@typescript-eslint/typescript-estree": "8.46.2", "@typescript-eslint/utils": "8.46.2" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <6.0.0" } }, "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg=="],
|
||||
|
||||
"undici-types": ["undici-types@7.14.0", "", {}, "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
|
||||
|
||||
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
|
||||
|
||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
||||
"@eslint/config-helpers/@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
|
||||
|
||||
"@eslint/plugin-kit/@eslint/core": ["@eslint/core@0.17.0", "", { "dependencies": { "@types/json-schema": "^7.0.15" } }, "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ=="],
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.5", "", {}, "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
|
||||
|
||||
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
||||
|
||||
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.2", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ=="],
|
||||
}
|
||||
}
|
||||
104
check.py
Executable file
104
check.py
Executable file
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
ADDITIONAL_PACKAGES_NODE = {}
|
||||
ADDITIONAL_PACKAGES_DENO = {
|
||||
"@types/node@22.5.4": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
||||
"undici-types@6.19.8": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
}
|
||||
BASE_PATH = pathlib.Path(__file__).parent
|
||||
|
||||
|
||||
def parse_deno() -> dict[str, str]:
|
||||
path = BASE_PATH / "deno.lock"
|
||||
with path.open("rb") as file:
|
||||
lockfile = json.load(file)
|
||||
|
||||
v = lockfile["version"]
|
||||
if v not in ("4", "5"):
|
||||
msg = f"Unsupported lockfile version: {v} (expected 4/5)"
|
||||
raise ValueError(msg)
|
||||
|
||||
integrities = {}
|
||||
for name, info in lockfile["npm"].items():
|
||||
integrity = info["integrity"]
|
||||
other = integrities.get(integrity)
|
||||
if other and other != name:
|
||||
msg = f"Duplicate integrity for {name} and {other}: {integrity}"
|
||||
raise ValueError(msg)
|
||||
|
||||
integrities[integrity] = name
|
||||
|
||||
return integrities
|
||||
|
||||
|
||||
def parse_node() -> dict[str, str]:
|
||||
path = BASE_PATH / "package-lock.json"
|
||||
with path.open("rb") as file:
|
||||
lockfile = json.load(file)
|
||||
|
||||
v = lockfile["lockfileVersion"]
|
||||
if v != 3:
|
||||
msg = f"Unsupported lockfile version: {v} (expected 3)"
|
||||
raise ValueError(msg)
|
||||
|
||||
integrities = {}
|
||||
for path, info in lockfile["packages"].items():
|
||||
if not path:
|
||||
continue
|
||||
|
||||
_, _, mod_name = path.rpartition("node_modules/")
|
||||
version = info["version"]
|
||||
name = f"{mod_name}@{version}"
|
||||
|
||||
integrity = info["integrity"]
|
||||
other = integrities.get(integrity)
|
||||
if other and other != name:
|
||||
msg = f"Duplicate integrity for {name} and {other}: {integrity}"
|
||||
raise ValueError(msg)
|
||||
integrities[integrity] = name
|
||||
|
||||
return integrities
|
||||
|
||||
|
||||
def main():
|
||||
try:
|
||||
packages_deno = parse_deno()
|
||||
except Exception as error:
|
||||
print(f"ERROR: Could not read deno lockfile: {error}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
packages_node = parse_node()
|
||||
except Exception as error:
|
||||
print(f"ERROR: Could not read npm lockfile: {error}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
packages_deno.update({v: k for k, v in ADDITIONAL_PACKAGES_NODE.items()})
|
||||
packages_node.update({v: k for k, v in ADDITIONAL_PACKAGES_DENO.items()})
|
||||
differences = packages_deno.keys() ^ packages_node.keys()
|
||||
|
||||
if diffs_deno := differences.intersection(packages_deno):
|
||||
print(
|
||||
"deno => npm:",
|
||||
*(f"{packages_deno[h]} ({h})" for h in diffs_deno),
|
||||
sep="\n\t",
|
||||
)
|
||||
|
||||
if diffs_node := differences.intersection(packages_node):
|
||||
print(
|
||||
" npm => deno:",
|
||||
*(f"{packages_node[h]} ({h})" for h in diffs_node),
|
||||
sep="\n\t",
|
||||
)
|
||||
|
||||
if differences:
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
871
deno.lock
generated
Normal file
871
deno.lock
generated
Normal file
@@ -0,0 +1,871 @@
|
||||
{
|
||||
"version": "4",
|
||||
"specifiers": {
|
||||
"npm:@eslint/js@9.38.0": "9.38.0",
|
||||
"npm:@types/bun@1.3.0": "1.3.0",
|
||||
"npm:@types/deno@2.5.0": "2.5.0",
|
||||
"npm:@types/node@24.8.1": "24.8.1",
|
||||
"npm:astring@1.9.0": "1.9.0",
|
||||
"npm:esbuild@0.28.0": "0.28.0",
|
||||
"npm:eslint@9.38.0": "9.38.0",
|
||||
"npm:globals@16.4.0": "16.4.0",
|
||||
"npm:meriyah@6.1.4": "6.1.4",
|
||||
"npm:prettier@3.6.2": "3.6.2",
|
||||
"npm:typescript-eslint@8.46.2": "8.46.2_eslint@9.38.0_typescript@5.9.3_@typescript-eslint+parser@8.46.2__eslint@9.38.0__typescript@5.9.3"
|
||||
},
|
||||
"npm": {
|
||||
"@esbuild/aix-ppc64@0.28.0": {
|
||||
"integrity": "sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA=="
|
||||
},
|
||||
"@esbuild/android-arm64@0.28.0": {
|
||||
"integrity": "sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw=="
|
||||
},
|
||||
"@esbuild/android-arm@0.28.0": {
|
||||
"integrity": "sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ=="
|
||||
},
|
||||
"@esbuild/android-x64@0.28.0": {
|
||||
"integrity": "sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA=="
|
||||
},
|
||||
"@esbuild/darwin-arm64@0.28.0": {
|
||||
"integrity": "sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q=="
|
||||
},
|
||||
"@esbuild/darwin-x64@0.28.0": {
|
||||
"integrity": "sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ=="
|
||||
},
|
||||
"@esbuild/freebsd-arm64@0.28.0": {
|
||||
"integrity": "sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q=="
|
||||
},
|
||||
"@esbuild/freebsd-x64@0.28.0": {
|
||||
"integrity": "sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw=="
|
||||
},
|
||||
"@esbuild/linux-arm64@0.28.0": {
|
||||
"integrity": "sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A=="
|
||||
},
|
||||
"@esbuild/linux-arm@0.28.0": {
|
||||
"integrity": "sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw=="
|
||||
},
|
||||
"@esbuild/linux-ia32@0.28.0": {
|
||||
"integrity": "sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ=="
|
||||
},
|
||||
"@esbuild/linux-loong64@0.28.0": {
|
||||
"integrity": "sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg=="
|
||||
},
|
||||
"@esbuild/linux-mips64el@0.28.0": {
|
||||
"integrity": "sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w=="
|
||||
},
|
||||
"@esbuild/linux-ppc64@0.28.0": {
|
||||
"integrity": "sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg=="
|
||||
},
|
||||
"@esbuild/linux-riscv64@0.28.0": {
|
||||
"integrity": "sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ=="
|
||||
},
|
||||
"@esbuild/linux-s390x@0.28.0": {
|
||||
"integrity": "sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q=="
|
||||
},
|
||||
"@esbuild/linux-x64@0.28.0": {
|
||||
"integrity": "sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ=="
|
||||
},
|
||||
"@esbuild/netbsd-arm64@0.28.0": {
|
||||
"integrity": "sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw=="
|
||||
},
|
||||
"@esbuild/netbsd-x64@0.28.0": {
|
||||
"integrity": "sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw=="
|
||||
},
|
||||
"@esbuild/openbsd-arm64@0.28.0": {
|
||||
"integrity": "sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g=="
|
||||
},
|
||||
"@esbuild/openbsd-x64@0.28.0": {
|
||||
"integrity": "sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA=="
|
||||
},
|
||||
"@esbuild/openharmony-arm64@0.28.0": {
|
||||
"integrity": "sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w=="
|
||||
},
|
||||
"@esbuild/sunos-x64@0.28.0": {
|
||||
"integrity": "sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw=="
|
||||
},
|
||||
"@esbuild/win32-arm64@0.28.0": {
|
||||
"integrity": "sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA=="
|
||||
},
|
||||
"@esbuild/win32-ia32@0.28.0": {
|
||||
"integrity": "sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA=="
|
||||
},
|
||||
"@esbuild/win32-x64@0.28.0": {
|
||||
"integrity": "sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw=="
|
||||
},
|
||||
"@eslint-community/eslint-utils@4.9.0_eslint@9.38.0": {
|
||||
"integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==",
|
||||
"dependencies": [
|
||||
"eslint",
|
||||
"eslint-visitor-keys@3.4.3"
|
||||
]
|
||||
},
|
||||
"@eslint-community/regexpp@4.12.2": {
|
||||
"integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew=="
|
||||
},
|
||||
"@eslint/config-array@0.21.1": {
|
||||
"integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==",
|
||||
"dependencies": [
|
||||
"@eslint/object-schema",
|
||||
"debug",
|
||||
"minimatch@3.1.2"
|
||||
]
|
||||
},
|
||||
"@eslint/config-helpers@0.4.2": {
|
||||
"integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
|
||||
"dependencies": [
|
||||
"@eslint/core@0.17.0"
|
||||
]
|
||||
},
|
||||
"@eslint/core@0.16.0": {
|
||||
"integrity": "sha512-nmC8/totwobIiFcGkDza3GIKfAw1+hLiYVrh3I1nIomQ8PEr5cxg34jnkmGawul/ep52wGRAcyeDCNtWKSOj4Q==",
|
||||
"dependencies": [
|
||||
"@types/json-schema"
|
||||
]
|
||||
},
|
||||
"@eslint/core@0.17.0": {
|
||||
"integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
|
||||
"dependencies": [
|
||||
"@types/json-schema"
|
||||
]
|
||||
},
|
||||
"@eslint/eslintrc@3.3.3": {
|
||||
"integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==",
|
||||
"dependencies": [
|
||||
"ajv",
|
||||
"debug",
|
||||
"espree",
|
||||
"globals@14.0.0",
|
||||
"ignore@5.3.2",
|
||||
"import-fresh",
|
||||
"js-yaml",
|
||||
"minimatch@3.1.2",
|
||||
"strip-json-comments"
|
||||
]
|
||||
},
|
||||
"@eslint/js@9.38.0": {
|
||||
"integrity": "sha512-UZ1VpFvXf9J06YG9xQBdnzU+kthors6KjhMAl6f4gH4usHyh31rUf2DLGInT8RFYIReYXNSydgPY0V2LuWgl7A=="
|
||||
},
|
||||
"@eslint/object-schema@2.1.7": {
|
||||
"integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA=="
|
||||
},
|
||||
"@eslint/plugin-kit@0.4.1": {
|
||||
"integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
|
||||
"dependencies": [
|
||||
"@eslint/core@0.17.0",
|
||||
"levn"
|
||||
]
|
||||
},
|
||||
"@humanfs/core@0.19.1": {
|
||||
"integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="
|
||||
},
|
||||
"@humanfs/node@0.16.7": {
|
||||
"integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
|
||||
"dependencies": [
|
||||
"@humanfs/core",
|
||||
"@humanwhocodes/retry"
|
||||
]
|
||||
},
|
||||
"@humanwhocodes/module-importer@1.0.1": {
|
||||
"integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA=="
|
||||
},
|
||||
"@humanwhocodes/retry@0.4.3": {
|
||||
"integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="
|
||||
},
|
||||
"@nodelib/fs.scandir@2.1.5": {
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.stat",
|
||||
"run-parallel"
|
||||
]
|
||||
},
|
||||
"@nodelib/fs.stat@2.0.5": {
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
|
||||
},
|
||||
"@nodelib/fs.walk@1.2.8": {
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.scandir",
|
||||
"fastq"
|
||||
]
|
||||
},
|
||||
"@types/bun@1.3.0": {
|
||||
"integrity": "sha512-+lAGCYjXjip2qY375xX/scJeVRmZ5cY0wyHYyCYxNcdEXrQ4AOe3gACgd4iQ8ksOslJtW4VNxBJ8llUwc3a6AA==",
|
||||
"dependencies": [
|
||||
"bun-types"
|
||||
]
|
||||
},
|
||||
"@types/deno@2.5.0": {
|
||||
"integrity": "sha512-g8JS38vmc0S87jKsFzre+0ZyMOUDHPVokEJymSCRlL57h6f/FdKPWBXgdFh3Z8Ees9sz11qt9VWELU9Y9ZkiVw=="
|
||||
},
|
||||
"@types/estree@1.0.8": {
|
||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="
|
||||
},
|
||||
"@types/json-schema@7.0.15": {
|
||||
"integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
|
||||
},
|
||||
"@types/node@22.5.4": {
|
||||
"integrity": "sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==",
|
||||
"dependencies": [
|
||||
"undici-types@6.19.8"
|
||||
]
|
||||
},
|
||||
"@types/node@24.8.1": {
|
||||
"integrity": "sha512-alv65KGRadQVfVcG69MuB4IzdYVpRwMG/mq8KWOaoOdyY617P5ivaDiMCGOFDWD2sAn5Q0mR3mRtUOgm99hL9Q==",
|
||||
"dependencies": [
|
||||
"undici-types@7.14.0"
|
||||
]
|
||||
},
|
||||
"@types/react@19.2.7": {
|
||||
"integrity": "sha512-MWtvHrGZLFttgeEj28VXHxpmwYbor/ATPYbBfSFZEIRK0ecCFLl2Qo55z52Hss+UV9CRN7trSeq1zbgx7YDWWg==",
|
||||
"dependencies": [
|
||||
"csstype"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/eslint-plugin@8.46.2_@typescript-eslint+parser@8.46.2__eslint@9.38.0__typescript@5.9.3_eslint@9.38.0_typescript@5.9.3": {
|
||||
"integrity": "sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==",
|
||||
"dependencies": [
|
||||
"@eslint-community/regexpp",
|
||||
"@typescript-eslint/parser",
|
||||
"@typescript-eslint/scope-manager",
|
||||
"@typescript-eslint/type-utils",
|
||||
"@typescript-eslint/utils",
|
||||
"@typescript-eslint/visitor-keys",
|
||||
"eslint",
|
||||
"graphemer",
|
||||
"ignore@7.0.5",
|
||||
"natural-compare",
|
||||
"ts-api-utils",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/parser@8.46.2_eslint@9.38.0_typescript@5.9.3": {
|
||||
"integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/scope-manager",
|
||||
"@typescript-eslint/types",
|
||||
"@typescript-eslint/typescript-estree",
|
||||
"@typescript-eslint/visitor-keys",
|
||||
"debug",
|
||||
"eslint",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/project-service@8.46.2_typescript@5.9.3": {
|
||||
"integrity": "sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/tsconfig-utils",
|
||||
"@typescript-eslint/types",
|
||||
"debug",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/scope-manager@8.46.2": {
|
||||
"integrity": "sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/types",
|
||||
"@typescript-eslint/visitor-keys"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/tsconfig-utils@8.46.2_typescript@5.9.3": {
|
||||
"integrity": "sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==",
|
||||
"dependencies": [
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/type-utils@8.46.2_eslint@9.38.0_typescript@5.9.3": {
|
||||
"integrity": "sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/types",
|
||||
"@typescript-eslint/typescript-estree",
|
||||
"@typescript-eslint/utils",
|
||||
"debug",
|
||||
"eslint",
|
||||
"ts-api-utils",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/types@8.46.2": {
|
||||
"integrity": "sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ=="
|
||||
},
|
||||
"@typescript-eslint/typescript-estree@8.46.2_typescript@5.9.3": {
|
||||
"integrity": "sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/project-service",
|
||||
"@typescript-eslint/tsconfig-utils",
|
||||
"@typescript-eslint/types",
|
||||
"@typescript-eslint/visitor-keys",
|
||||
"debug",
|
||||
"fast-glob",
|
||||
"is-glob",
|
||||
"minimatch@9.0.5",
|
||||
"semver",
|
||||
"ts-api-utils",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/utils@8.46.2_eslint@9.38.0_typescript@5.9.3": {
|
||||
"integrity": "sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==",
|
||||
"dependencies": [
|
||||
"@eslint-community/eslint-utils",
|
||||
"@typescript-eslint/scope-manager",
|
||||
"@typescript-eslint/types",
|
||||
"@typescript-eslint/typescript-estree",
|
||||
"eslint",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"@typescript-eslint/visitor-keys@8.46.2": {
|
||||
"integrity": "sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/types",
|
||||
"eslint-visitor-keys@4.2.1"
|
||||
]
|
||||
},
|
||||
"acorn-jsx@5.3.2_acorn@8.15.0": {
|
||||
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
|
||||
"dependencies": [
|
||||
"acorn"
|
||||
]
|
||||
},
|
||||
"acorn@8.15.0": {
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg=="
|
||||
},
|
||||
"ajv@6.12.6": {
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"dependencies": [
|
||||
"fast-deep-equal",
|
||||
"fast-json-stable-stringify",
|
||||
"json-schema-traverse",
|
||||
"uri-js"
|
||||
]
|
||||
},
|
||||
"ansi-styles@4.3.0": {
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": [
|
||||
"color-convert"
|
||||
]
|
||||
},
|
||||
"argparse@2.0.1": {
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"astring@1.9.0": {
|
||||
"integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg=="
|
||||
},
|
||||
"balanced-match@1.0.2": {
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"brace-expansion@1.1.12": {
|
||||
"integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
|
||||
"dependencies": [
|
||||
"balanced-match",
|
||||
"concat-map"
|
||||
]
|
||||
},
|
||||
"brace-expansion@2.0.2": {
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dependencies": [
|
||||
"balanced-match"
|
||||
]
|
||||
},
|
||||
"braces@3.0.3": {
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dependencies": [
|
||||
"fill-range"
|
||||
]
|
||||
},
|
||||
"bun-types@1.3.0_@types+react@19.2.7": {
|
||||
"integrity": "sha512-u8X0thhx+yJ0KmkxuEo9HAtdfgCBaM/aI9K90VQcQioAmkVp3SG3FkwWGibUFz3WdXAdcsqOcbU40lK7tbHdkQ==",
|
||||
"dependencies": [
|
||||
"@types/node@22.5.4",
|
||||
"@types/react"
|
||||
]
|
||||
},
|
||||
"callsites@3.1.0": {
|
||||
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="
|
||||
},
|
||||
"chalk@4.1.2": {
|
||||
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
|
||||
"dependencies": [
|
||||
"ansi-styles",
|
||||
"supports-color"
|
||||
]
|
||||
},
|
||||
"color-convert@2.0.1": {
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": [
|
||||
"color-name"
|
||||
]
|
||||
},
|
||||
"color-name@1.1.4": {
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"concat-map@0.0.1": {
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"cross-spawn@7.0.6": {
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dependencies": [
|
||||
"path-key",
|
||||
"shebang-command",
|
||||
"which"
|
||||
]
|
||||
},
|
||||
"csstype@3.2.3": {
|
||||
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="
|
||||
},
|
||||
"debug@4.4.3": {
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dependencies": [
|
||||
"ms"
|
||||
]
|
||||
},
|
||||
"deep-is@0.1.4": {
|
||||
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
|
||||
},
|
||||
"esbuild@0.28.0": {
|
||||
"integrity": "sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==",
|
||||
"dependencies": [
|
||||
"@esbuild/aix-ppc64",
|
||||
"@esbuild/android-arm",
|
||||
"@esbuild/android-arm64",
|
||||
"@esbuild/android-x64",
|
||||
"@esbuild/darwin-arm64",
|
||||
"@esbuild/darwin-x64",
|
||||
"@esbuild/freebsd-arm64",
|
||||
"@esbuild/freebsd-x64",
|
||||
"@esbuild/linux-arm",
|
||||
"@esbuild/linux-arm64",
|
||||
"@esbuild/linux-ia32",
|
||||
"@esbuild/linux-loong64",
|
||||
"@esbuild/linux-mips64el",
|
||||
"@esbuild/linux-ppc64",
|
||||
"@esbuild/linux-riscv64",
|
||||
"@esbuild/linux-s390x",
|
||||
"@esbuild/linux-x64",
|
||||
"@esbuild/netbsd-arm64",
|
||||
"@esbuild/netbsd-x64",
|
||||
"@esbuild/openbsd-arm64",
|
||||
"@esbuild/openbsd-x64",
|
||||
"@esbuild/openharmony-arm64",
|
||||
"@esbuild/sunos-x64",
|
||||
"@esbuild/win32-arm64",
|
||||
"@esbuild/win32-ia32",
|
||||
"@esbuild/win32-x64"
|
||||
]
|
||||
},
|
||||
"escape-string-regexp@4.0.0": {
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
|
||||
},
|
||||
"eslint-scope@8.4.0": {
|
||||
"integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
|
||||
"dependencies": [
|
||||
"esrecurse",
|
||||
"estraverse"
|
||||
]
|
||||
},
|
||||
"eslint-visitor-keys@3.4.3": {
|
||||
"integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="
|
||||
},
|
||||
"eslint-visitor-keys@4.2.1": {
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ=="
|
||||
},
|
||||
"eslint@9.38.0": {
|
||||
"integrity": "sha512-t5aPOpmtJcZcz5UJyY2GbvpDlsK5E8JqRqoKtfiKE3cNh437KIqfJr3A3AKf5k64NPx6d0G3dno6XDY05PqPtw==",
|
||||
"dependencies": [
|
||||
"@eslint-community/eslint-utils",
|
||||
"@eslint-community/regexpp",
|
||||
"@eslint/config-array",
|
||||
"@eslint/config-helpers",
|
||||
"@eslint/core@0.16.0",
|
||||
"@eslint/eslintrc",
|
||||
"@eslint/js",
|
||||
"@eslint/plugin-kit",
|
||||
"@humanfs/node",
|
||||
"@humanwhocodes/module-importer",
|
||||
"@humanwhocodes/retry",
|
||||
"@types/estree",
|
||||
"ajv",
|
||||
"chalk",
|
||||
"cross-spawn",
|
||||
"debug",
|
||||
"escape-string-regexp",
|
||||
"eslint-scope",
|
||||
"eslint-visitor-keys@4.2.1",
|
||||
"espree",
|
||||
"esquery",
|
||||
"esutils",
|
||||
"fast-deep-equal",
|
||||
"file-entry-cache",
|
||||
"find-up",
|
||||
"glob-parent@6.0.2",
|
||||
"ignore@5.3.2",
|
||||
"imurmurhash",
|
||||
"is-glob",
|
||||
"json-stable-stringify-without-jsonify",
|
||||
"lodash.merge",
|
||||
"minimatch@3.1.2",
|
||||
"natural-compare",
|
||||
"optionator"
|
||||
]
|
||||
},
|
||||
"espree@10.4.0_acorn@8.15.0": {
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dependencies": [
|
||||
"acorn",
|
||||
"acorn-jsx",
|
||||
"eslint-visitor-keys@4.2.1"
|
||||
]
|
||||
},
|
||||
"esquery@1.6.0": {
|
||||
"integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
|
||||
"dependencies": [
|
||||
"estraverse"
|
||||
]
|
||||
},
|
||||
"esrecurse@4.3.0": {
|
||||
"integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
|
||||
"dependencies": [
|
||||
"estraverse"
|
||||
]
|
||||
},
|
||||
"estraverse@5.3.0": {
|
||||
"integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
|
||||
},
|
||||
"esutils@2.0.3": {
|
||||
"integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
|
||||
},
|
||||
"fast-deep-equal@3.1.3": {
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
|
||||
},
|
||||
"fast-glob@3.3.3": {
|
||||
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.stat",
|
||||
"@nodelib/fs.walk",
|
||||
"glob-parent@5.1.2",
|
||||
"merge2",
|
||||
"micromatch"
|
||||
]
|
||||
},
|
||||
"fast-json-stable-stringify@2.1.0": {
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"fast-levenshtein@2.0.6": {
|
||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
|
||||
},
|
||||
"fastq@1.19.1": {
|
||||
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
|
||||
"dependencies": [
|
||||
"reusify"
|
||||
]
|
||||
},
|
||||
"file-entry-cache@8.0.0": {
|
||||
"integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
|
||||
"dependencies": [
|
||||
"flat-cache"
|
||||
]
|
||||
},
|
||||
"fill-range@7.1.1": {
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dependencies": [
|
||||
"to-regex-range"
|
||||
]
|
||||
},
|
||||
"find-up@5.0.0": {
|
||||
"integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
|
||||
"dependencies": [
|
||||
"locate-path",
|
||||
"path-exists"
|
||||
]
|
||||
},
|
||||
"flat-cache@4.0.1": {
|
||||
"integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
|
||||
"dependencies": [
|
||||
"flatted",
|
||||
"keyv"
|
||||
]
|
||||
},
|
||||
"flatted@3.3.3": {
|
||||
"integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="
|
||||
},
|
||||
"glob-parent@5.1.2": {
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dependencies": [
|
||||
"is-glob"
|
||||
]
|
||||
},
|
||||
"glob-parent@6.0.2": {
|
||||
"integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
|
||||
"dependencies": [
|
||||
"is-glob"
|
||||
]
|
||||
},
|
||||
"globals@14.0.0": {
|
||||
"integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="
|
||||
},
|
||||
"globals@16.4.0": {
|
||||
"integrity": "sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw=="
|
||||
},
|
||||
"graphemer@1.4.0": {
|
||||
"integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="
|
||||
},
|
||||
"has-flag@4.0.0": {
|
||||
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
|
||||
},
|
||||
"ignore@5.3.2": {
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
|
||||
},
|
||||
"ignore@7.0.5": {
|
||||
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg=="
|
||||
},
|
||||
"import-fresh@3.3.1": {
|
||||
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
|
||||
"dependencies": [
|
||||
"parent-module",
|
||||
"resolve-from"
|
||||
]
|
||||
},
|
||||
"imurmurhash@0.1.4": {
|
||||
"integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="
|
||||
},
|
||||
"is-extglob@2.1.1": {
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
|
||||
},
|
||||
"is-glob@4.0.3": {
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dependencies": [
|
||||
"is-extglob"
|
||||
]
|
||||
},
|
||||
"is-number@7.0.0": {
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"isexe@2.0.0": {
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"js-yaml@4.1.1": {
|
||||
"integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
|
||||
"dependencies": [
|
||||
"argparse"
|
||||
]
|
||||
},
|
||||
"json-buffer@3.0.1": {
|
||||
"integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ=="
|
||||
},
|
||||
"json-schema-traverse@0.4.1": {
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
|
||||
},
|
||||
"json-stable-stringify-without-jsonify@1.0.1": {
|
||||
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw=="
|
||||
},
|
||||
"keyv@4.5.4": {
|
||||
"integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
|
||||
"dependencies": [
|
||||
"json-buffer"
|
||||
]
|
||||
},
|
||||
"levn@0.4.1": {
|
||||
"integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
|
||||
"dependencies": [
|
||||
"prelude-ls",
|
||||
"type-check"
|
||||
]
|
||||
},
|
||||
"locate-path@6.0.0": {
|
||||
"integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
|
||||
"dependencies": [
|
||||
"p-locate"
|
||||
]
|
||||
},
|
||||
"lodash.merge@4.6.2": {
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="
|
||||
},
|
||||
"merge2@1.4.1": {
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
|
||||
},
|
||||
"meriyah@6.1.4": {
|
||||
"integrity": "sha512-Sz8FzjzI0kN13GK/6MVEsVzMZEPvOhnmmI1lU5+/1cGOiK3QUahntrNNtdVeihrO7t9JpoH75iMNXg6R6uWflQ=="
|
||||
},
|
||||
"micromatch@4.0.8": {
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dependencies": [
|
||||
"braces",
|
||||
"picomatch"
|
||||
]
|
||||
},
|
||||
"minimatch@3.1.2": {
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": [
|
||||
"brace-expansion@1.1.12"
|
||||
]
|
||||
},
|
||||
"minimatch@9.0.5": {
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"dependencies": [
|
||||
"brace-expansion@2.0.2"
|
||||
]
|
||||
},
|
||||
"ms@2.1.3": {
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||
},
|
||||
"natural-compare@1.4.0": {
|
||||
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
|
||||
},
|
||||
"optionator@0.9.4": {
|
||||
"integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
|
||||
"dependencies": [
|
||||
"deep-is",
|
||||
"fast-levenshtein",
|
||||
"levn",
|
||||
"prelude-ls",
|
||||
"type-check",
|
||||
"word-wrap"
|
||||
]
|
||||
},
|
||||
"p-limit@3.1.0": {
|
||||
"integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
|
||||
"dependencies": [
|
||||
"yocto-queue"
|
||||
]
|
||||
},
|
||||
"p-locate@5.0.0": {
|
||||
"integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
|
||||
"dependencies": [
|
||||
"p-limit"
|
||||
]
|
||||
},
|
||||
"parent-module@1.0.1": {
|
||||
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
|
||||
"dependencies": [
|
||||
"callsites"
|
||||
]
|
||||
},
|
||||
"path-exists@4.0.0": {
|
||||
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
|
||||
},
|
||||
"path-key@3.1.1": {
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
|
||||
},
|
||||
"picomatch@2.3.1": {
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
},
|
||||
"prelude-ls@1.2.1": {
|
||||
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
|
||||
},
|
||||
"prettier@3.6.2": {
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="
|
||||
},
|
||||
"punycode@2.3.1": {
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
|
||||
},
|
||||
"queue-microtask@1.2.3": {
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
|
||||
},
|
||||
"resolve-from@4.0.0": {
|
||||
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="
|
||||
},
|
||||
"reusify@1.1.0": {
|
||||
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="
|
||||
},
|
||||
"run-parallel@1.2.0": {
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dependencies": [
|
||||
"queue-microtask"
|
||||
]
|
||||
},
|
||||
"semver@7.7.3": {
|
||||
"integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="
|
||||
},
|
||||
"shebang-command@2.0.0": {
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dependencies": [
|
||||
"shebang-regex"
|
||||
]
|
||||
},
|
||||
"shebang-regex@3.0.0": {
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
|
||||
},
|
||||
"strip-json-comments@3.1.1": {
|
||||
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="
|
||||
},
|
||||
"supports-color@7.2.0": {
|
||||
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
|
||||
"dependencies": [
|
||||
"has-flag"
|
||||
]
|
||||
},
|
||||
"to-regex-range@5.0.1": {
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dependencies": [
|
||||
"is-number"
|
||||
]
|
||||
},
|
||||
"ts-api-utils@2.1.0_typescript@5.9.3": {
|
||||
"integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==",
|
||||
"dependencies": [
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"type-check@0.4.0": {
|
||||
"integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
|
||||
"dependencies": [
|
||||
"prelude-ls"
|
||||
]
|
||||
},
|
||||
"typescript-eslint@8.46.2_eslint@9.38.0_typescript@5.9.3_@typescript-eslint+parser@8.46.2__eslint@9.38.0__typescript@5.9.3": {
|
||||
"integrity": "sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==",
|
||||
"dependencies": [
|
||||
"@typescript-eslint/eslint-plugin",
|
||||
"@typescript-eslint/parser",
|
||||
"@typescript-eslint/typescript-estree",
|
||||
"@typescript-eslint/utils",
|
||||
"eslint",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"typescript@5.9.3": {
|
||||
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="
|
||||
},
|
||||
"undici-types@6.19.8": {
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="
|
||||
},
|
||||
"undici-types@7.14.0": {
|
||||
"integrity": "sha512-QQiYxHuyZ9gQUIrmPo3IA+hUl4KYk8uSA7cHrcKd/l3p1OTpZcM0Tbp9x7FAtXdAYhlasd60ncPpgu6ihG6TOA=="
|
||||
},
|
||||
"uri-js@4.4.1": {
|
||||
"integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
|
||||
"dependencies": [
|
||||
"punycode"
|
||||
]
|
||||
},
|
||||
"which@2.0.2": {
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dependencies": [
|
||||
"isexe"
|
||||
]
|
||||
},
|
||||
"word-wrap@1.2.5": {
|
||||
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="
|
||||
},
|
||||
"yocto-queue@0.1.0": {
|
||||
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"packageJson": {
|
||||
"dependencies": [
|
||||
"npm:@eslint/js@9.38.0",
|
||||
"npm:@types/bun@1.3.0",
|
||||
"npm:@types/deno@2.5.0",
|
||||
"npm:@types/node@24.8.1",
|
||||
"npm:astring@1.9.0",
|
||||
"npm:esbuild@0.28.0",
|
||||
"npm:eslint@9.38.0",
|
||||
"npm:globals@16.4.0",
|
||||
"npm:meriyah@6.1.4",
|
||||
"npm:prettier@3.6.2",
|
||||
"npm:typescript-eslint@8.46.2"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
433
hatch_build.py
Normal file → Executable file
433
hatch_build.py
Normal file → Executable file
@@ -1,36 +1,142 @@
|
||||
#!/usr/bin/env python
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import pathlib
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import typing
|
||||
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
try:
|
||||
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
|
||||
except ImportError:
|
||||
BuildHookInterface = object
|
||||
|
||||
|
||||
BASE_PATH = pathlib.Path(__file__).parent.resolve()
|
||||
DEFAULT_BUNDLER = ["esbuild", "pnpm", "deno", "bun", "node"]
|
||||
DEFAULT_INSTALLER = ["pnpm", "deno", "bun", "npm"]
|
||||
|
||||
|
||||
def run():
|
||||
if not os.environ.get("EJS_BUILD_SKIP_INSTALL"):
|
||||
name, path = find_executable("EJS_BUILD_INSTALLER", DEFAULT_INSTALLER)
|
||||
args, env = build_install_args(name)
|
||||
cmd = [path, *args]
|
||||
print(f"Install command: {shlex.join(cmd)}")
|
||||
subprocess.run(cmd, env=env, check=False)
|
||||
|
||||
esbuild = ESBuild(*find_executable("EJS_BUILD_BUNDLER", DEFAULT_BUNDLER))
|
||||
print(f"Bundle command: {shlex.join(esbuild.cmd)}", file=sys.stderr)
|
||||
|
||||
externals = list(get_external_packages(esbuild))
|
||||
builds = create_builds(externals)
|
||||
print("SHA3-512 checksums:", file=sys.stderr)
|
||||
for build in builds:
|
||||
outfile = build.get("outfile")
|
||||
assert outfile
|
||||
esbuild.run(build)
|
||||
|
||||
path = BASE_PATH / outfile
|
||||
# Workaround for https://github.com/evanw/esbuild/issues/3717#issuecomment-3765731197
|
||||
data = path.read_bytes()
|
||||
if not build.get("minify"):
|
||||
data = re.sub(
|
||||
rb"^\s+// node_modules[^\n]+$",
|
||||
b"",
|
||||
data,
|
||||
flags=re.ASCII | re.MULTILINE,
|
||||
)
|
||||
path.write_bytes(data)
|
||||
digest = hashlib.sha3_512(data).hexdigest()
|
||||
print(f"{digest} {path.name}")
|
||||
|
||||
|
||||
def create_builds(externals: list[Package]) -> list[ESBuildOptions]:
|
||||
with (BASE_PATH / "package.json").open("rb") as file:
|
||||
pkg = json.load(file)
|
||||
LICENSE_PREAMBLE = (
|
||||
"SPDX-License-Identifier: Unlicense\n"
|
||||
+ f"This file was automatically generated by {pkg['homepage']}"
|
||||
)
|
||||
BANNER_WITHOUT_DEPENDENCIES = {"js": license_comment(LICENSE_PREAMBLE)}
|
||||
BANNER_WITH_DEPENDENCIES = {
|
||||
"js": license_comment(
|
||||
LICENSE_PREAMBLE
|
||||
+ "\n\nBundled dependencies:\n\n"
|
||||
+ "------\n\n".join(map(Package.license_comment, externals))
|
||||
)
|
||||
}
|
||||
EXTERNALS = [pkg.name for pkg in externals]
|
||||
ALIASES_DENO = {pkg.name: f"npm:{pkg.name}@{pkg.version}" for pkg in externals}
|
||||
ALIASES_BUN = {pkg.name: f"{pkg.name}@{pkg.version}" for pkg in externals}
|
||||
|
||||
return [
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/main.ts"],
|
||||
"outfile": "dist/yt.solver.core.js",
|
||||
"format": "iife",
|
||||
"globalName": "jsc",
|
||||
"banner": BANNER_WITHOUT_DEPENDENCIES,
|
||||
"external": EXTERNALS,
|
||||
},
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/main.ts"],
|
||||
"outfile": "dist/yt.solver.core.min.js",
|
||||
"minify": True,
|
||||
"format": "iife",
|
||||
"globalName": "jsc",
|
||||
"banner": BANNER_WITHOUT_DEPENDENCIES,
|
||||
"external": EXTERNALS,
|
||||
},
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/lib.ts"],
|
||||
"outfile": "dist/yt.solver.lib.js",
|
||||
"format": "iife",
|
||||
"globalName": "lib",
|
||||
"banner": BANNER_WITH_DEPENDENCIES,
|
||||
},
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/lib.ts"],
|
||||
"outfile": "dist/yt.solver.lib.min.js",
|
||||
"minify": True,
|
||||
"format": "iife",
|
||||
"globalName": "lib",
|
||||
"banner": BANNER_WITH_DEPENDENCIES,
|
||||
},
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/lib.ts"],
|
||||
"outfile": "dist/yt.solver.bun.lib.js",
|
||||
"minifySyntax": True,
|
||||
"format": "esm",
|
||||
"globalName": "lib",
|
||||
"banner": BANNER_WITHOUT_DEPENDENCIES,
|
||||
"alias": ALIASES_BUN,
|
||||
"external": list(ALIASES_BUN.values()),
|
||||
},
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/lib.ts"],
|
||||
"outfile": "dist/yt.solver.deno.lib.js",
|
||||
"minifySyntax": True,
|
||||
"format": "esm",
|
||||
"globalName": "lib",
|
||||
"banner": BANNER_WITHOUT_DEPENDENCIES,
|
||||
"alias": ALIASES_DENO,
|
||||
"external": list(ALIASES_DENO.values()),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
class CustomBuildHook(BuildHookInterface):
|
||||
def initialize(self, version, build_data):
|
||||
if shutil.which("deno"):
|
||||
print("Building with deno...", flush=True)
|
||||
os.environ["DENO_NO_UPDATE_CHECK"] = "1"
|
||||
subprocess.run(["deno", "install"], check=True)
|
||||
subprocess.run(["deno", "task", "bundle"], check=True)
|
||||
|
||||
elif shutil.which("bun"):
|
||||
print("Building with bun...", flush=True)
|
||||
subprocess.run(["bun", "install"], check=True)
|
||||
subprocess.run(["bun", "--bun", "run", "bundle"], check=True)
|
||||
|
||||
elif shutil.which("npm"):
|
||||
print("Building with npm...", flush=True)
|
||||
# npm is a batch file (`npm.cmd`) on windows, which requires `shell=True`
|
||||
requires_shell = os.name == "nt"
|
||||
subprocess.run(["npm", "install"], check=True, shell=requires_shell)
|
||||
subprocess.run(["npm", "run", "bundle"], check=True, shell=requires_shell)
|
||||
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"One of 'deno', 'bun', or 'npm' could not be found. "
|
||||
"Please install one of them to proceed with the build."
|
||||
)
|
||||
|
||||
run()
|
||||
build_data["force_include"].update(
|
||||
{
|
||||
"dist/yt.solver.core.min.js": "yt_dlp_ejs/yt/solver/core.min.js",
|
||||
@@ -40,3 +146,280 @@ class CustomBuildHook(BuildHookInterface):
|
||||
|
||||
def clean(self, versions):
|
||||
shutil.rmtree("node_modules", ignore_errors=True)
|
||||
|
||||
|
||||
def find_executable(env: str, defaults: list[str]):
|
||||
values = defaults
|
||||
if value := os.getenv(env):
|
||||
values = value.split(os.path.pathsep)
|
||||
for value in values:
|
||||
if path := shutil.which(value):
|
||||
name = pathlib.Path(path).name.partition(".")[0]
|
||||
return name, path
|
||||
|
||||
return None, ""
|
||||
|
||||
|
||||
def build_install_args(name: str | None):
|
||||
if name == "pnpm":
|
||||
return ["install", "--frozen-lockfile"], None
|
||||
|
||||
if name == "deno":
|
||||
env = os.environ.copy()
|
||||
env["DENO_NO_UPDATE_CHECK"] = "1"
|
||||
return ["install", "--frozen"], env
|
||||
|
||||
if name == "bun":
|
||||
return ["install", "--frozen-lockfile"], None
|
||||
|
||||
if name == "npm":
|
||||
return ["ci"], None
|
||||
|
||||
raise RuntimeError(
|
||||
"Only 'pnpm', 'deno', 'bun', or 'npm' are supported for installing dependencies. "
|
||||
"Please install one of them or pass EJS_BUILD_SKIP_INSTALL=1 to skip install step."
|
||||
)
|
||||
|
||||
|
||||
class ESBuild:
|
||||
def __init__(self, name: str | None, path: str, /):
|
||||
self._stdin = True
|
||||
self._env = None
|
||||
|
||||
if name == "esbuild":
|
||||
self._stdin = False
|
||||
self.cmd = [path]
|
||||
|
||||
elif name == "pnpm":
|
||||
self._stdin = False
|
||||
self.cmd = [path, "run", "esbuild"]
|
||||
|
||||
elif name == "deno":
|
||||
self._env = os.environ.copy()
|
||||
self._env["DENO_NO_UPDATE_CHECK"] = "1"
|
||||
self.cmd = [
|
||||
path,
|
||||
"run",
|
||||
"--allow-read",
|
||||
"--allow-env",
|
||||
"--allow-run",
|
||||
"build.mjs",
|
||||
]
|
||||
|
||||
elif name == "bun":
|
||||
self.cmd = [path, "--bun", "run", "build.mjs"]
|
||||
|
||||
elif name == "node":
|
||||
self.cmd = [path, "build.mjs"]
|
||||
|
||||
else:
|
||||
raise RuntimeError(
|
||||
"One of 'esbuild', 'pnpm', 'deno', 'bun', or 'node' could not be found. "
|
||||
"Please install one of them to be able to run esbuild."
|
||||
)
|
||||
|
||||
def run(self, options: ESBuildOptions, /):
|
||||
options = options.copy()
|
||||
if entrypoints := options.get("entryPoints"):
|
||||
options["entryPoints"] = [str(BASE_PATH / path) for path in entrypoints]
|
||||
if outfile := options.get("outfile"):
|
||||
options["outfile"] = str(BASE_PATH / outfile)
|
||||
|
||||
if self._stdin:
|
||||
process = self._run(self.cmd, json.dumps({"bundle": True, **options}))
|
||||
return json.loads(process.stdout)
|
||||
|
||||
cmd = [*self.cmd, "--bundle", *self._convert_args(options)]
|
||||
fd = name = None
|
||||
if options.pop("metafile", None):
|
||||
fd, name = tempfile.mkstemp(prefix="ejs-build-metadata-", suffix=".json")
|
||||
cmd.append(f"--metafile={name}")
|
||||
|
||||
try:
|
||||
self._run(cmd)
|
||||
if fd and name:
|
||||
with open(fd, "rb", closefd=True) as file:
|
||||
return json.load(file)
|
||||
return None
|
||||
finally:
|
||||
if name:
|
||||
os.unlink(name)
|
||||
|
||||
def _run(self, cmd: list[str], stdin: str | None = None, /):
|
||||
process = subprocess.run(
|
||||
cmd,
|
||||
env=self._env,
|
||||
input=stdin,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
check=False,
|
||||
)
|
||||
if process.returncode:
|
||||
raise RuntimeError(
|
||||
f"failed to run esbuild:\n{process.stdout}{process.stderr}"
|
||||
)
|
||||
return process
|
||||
|
||||
@staticmethod
|
||||
def _convert_args(options: ESBuildOptions):
|
||||
for entrypoint in options.pop("entryPoints", ()):
|
||||
yield entrypoint
|
||||
if not options.pop("write", True):
|
||||
options["outfile"] = "NUL" if os.name == "nt" else "/dev/null"
|
||||
|
||||
for name, value in options.items():
|
||||
parameter = "--" + re.sub(r"[A-Z]", lambda x: "-" + x[0].lower(), name)
|
||||
if isinstance(value, bool):
|
||||
yield f"{parameter}={str(value).lower()}"
|
||||
elif isinstance(value, str):
|
||||
yield f"{parameter}={value}"
|
||||
elif isinstance(value, list):
|
||||
if name == "absPaths":
|
||||
v = ",".join(value)
|
||||
yield f"{parameter}={v}"
|
||||
else:
|
||||
for v in value:
|
||||
yield f"{parameter}:{v}"
|
||||
elif isinstance(value, dict):
|
||||
for k, v in value.items():
|
||||
yield f"{parameter}:{k}={v}"
|
||||
|
||||
|
||||
class ESBuildOptions(typing.TypedDict, total=False):
|
||||
entryPoints: list[str]
|
||||
write: bool
|
||||
absPaths: list[str]
|
||||
metafile: bool
|
||||
outfile: str
|
||||
minify: bool
|
||||
minifySyntax: bool
|
||||
format: str
|
||||
globalName: str
|
||||
banner: dict[str, str]
|
||||
alias: dict[str, str]
|
||||
external: list[str]
|
||||
|
||||
|
||||
def get_external_packages(esbuild: ESBuild):
|
||||
metafile = esbuild.run(
|
||||
{
|
||||
"entryPoints": ["src/yt/solver/lib.ts"],
|
||||
"absPaths": ["metafile"],
|
||||
"metafile": True,
|
||||
"write": False,
|
||||
}
|
||||
)
|
||||
if not metafile:
|
||||
raise RuntimeError("failed to gather build metadata")
|
||||
|
||||
_externals = {}
|
||||
for input_file, meta in metafile["inputs"].items():
|
||||
try:
|
||||
pathlib.Path(input_file).relative_to(BASE_PATH)
|
||||
except ValueError:
|
||||
continue
|
||||
for import_meta in meta["imports"]:
|
||||
if "." in (import_meta.get("original") or ""):
|
||||
continue
|
||||
path = pathlib.Path(import_meta["path"])
|
||||
_externals[path] = None
|
||||
|
||||
for path in _externals:
|
||||
current = path.parent
|
||||
while current != BASE_PATH:
|
||||
package_path = current / "package.json"
|
||||
if package_path.is_file():
|
||||
break
|
||||
current = current.parent
|
||||
else:
|
||||
msg = f"Failed to find package dir for {path}"
|
||||
raise ValueError(msg)
|
||||
|
||||
yield Package.parse(current / "package.json")
|
||||
|
||||
|
||||
class Package:
|
||||
def __init__(
|
||||
self,
|
||||
/,
|
||||
name: str,
|
||||
description: str,
|
||||
version: str,
|
||||
author: str,
|
||||
repository: str,
|
||||
license: str,
|
||||
license_text: str,
|
||||
):
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.version = version
|
||||
self.author = author
|
||||
self.repository = repository
|
||||
self.license = license
|
||||
self.license_text = license_text
|
||||
|
||||
@staticmethod
|
||||
def _parse_author(author):
|
||||
if isinstance(author, str):
|
||||
return author
|
||||
|
||||
result = [author["name"]]
|
||||
if email := author.get("email"):
|
||||
result.append(f"<{email}>")
|
||||
if url := author.get("url"):
|
||||
result.append(f"({url})")
|
||||
return " ".join(result)
|
||||
|
||||
@classmethod
|
||||
def parse(cls, path: pathlib.Path, /):
|
||||
with path.open("rb") as file:
|
||||
data = json.load(file)
|
||||
|
||||
licenses = list(path.parent.glob("LICENSE*"))
|
||||
if len(licenses) != 1:
|
||||
msg = "could not find appropriate license"
|
||||
raise ValueError(msg)
|
||||
|
||||
return cls(
|
||||
name=data["name"],
|
||||
version=data["version"],
|
||||
author=cls._parse_author(data["author"]),
|
||||
description=data["description"],
|
||||
repository=data["repository"]["url"],
|
||||
license=data["license"],
|
||||
license_text=licenses[0].read_text(encoding="utf-8"),
|
||||
)
|
||||
|
||||
def _license_comment(self, /):
|
||||
for name in (
|
||||
"name",
|
||||
"description",
|
||||
"version",
|
||||
"author",
|
||||
"repository",
|
||||
"license",
|
||||
"license_text",
|
||||
):
|
||||
if name == "license_text":
|
||||
yield "\n"
|
||||
else:
|
||||
yield name.capitalize()
|
||||
yield ": "
|
||||
yield getattr(self, name)
|
||||
yield "\n"
|
||||
|
||||
def license_comment(self, /):
|
||||
return "".join(self._license_comment())
|
||||
|
||||
|
||||
def license_comment(data: str):
|
||||
return "/*!\n * " + "\n * ".join(data.splitlines()) + "\n */"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
run()
|
||||
except RuntimeError as error:
|
||||
print("ERROR:", error.args[0], file=sys.stderr)
|
||||
sys.exit(128)
|
||||
|
||||
2244
package-lock.json
generated
Normal file
2244
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
17
package.json
17
package.json
@@ -2,28 +2,27 @@
|
||||
"name": "ejs",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"bundle": "rollup -c",
|
||||
"fmt": "prettier --write \"src/**.ts\" \"package.json\" \"rollup.config.js\" \"run.ts\" \"eslint.config.js\"",
|
||||
"fmt:check": "prettier --check \"src/**.ts\" \"package.json\" \"rollup.config.js\" \"run.ts\" \"eslint.config.js\"",
|
||||
"lint": "eslint src"
|
||||
"bundle": "python hatch_build.py",
|
||||
"esbuild": "esbuild",
|
||||
"fmt": "prettier --write \"**/*.[jt]s\" \"package.json\"",
|
||||
"fmt:check": "prettier --check \"**/*.[jt]s\" \"package.json\"",
|
||||
"lint": "eslint src",
|
||||
"prettier": "prettier"
|
||||
},
|
||||
"homepage": "https://github.com/yt-dlp/ejs",
|
||||
"dependencies": {
|
||||
"astring": "1.9.0",
|
||||
"meriyah": "6.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "9.38.0",
|
||||
"@rollup/plugin-node-resolve": "16.0.3",
|
||||
"@rollup/plugin-sucrase": "5.0.2",
|
||||
"@rollup/plugin-terser": "0.4.4",
|
||||
"@types/bun": "1.3.0",
|
||||
"@types/deno": "2.5.0",
|
||||
"@types/node": "24.8.1",
|
||||
"esbuild": "0.28.0",
|
||||
"eslint": "9.38.0",
|
||||
"globals": "16.4.0",
|
||||
"prettier": "3.6.2",
|
||||
"rollup": "4.52.5",
|
||||
"rollup-plugin-license": "3.6.0",
|
||||
"typescript-eslint": "8.46.2"
|
||||
}
|
||||
}
|
||||
|
||||
1391
pnpm-lock.yaml
generated
Normal file
1391
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -47,6 +47,7 @@ source = "vcs"
|
||||
exclude = [
|
||||
"/.github/**",
|
||||
"/src/yt/solver/test/players/*",
|
||||
"!/src/yt/solver/test/players/.gitignore",
|
||||
]
|
||||
|
||||
[tool.hatch.build.targets.wheel]
|
||||
|
||||
250
rollup.config.js
250
rollup.config.js
@@ -1,250 +0,0 @@
|
||||
import { defineConfig } from "rollup";
|
||||
import nodeResolve from "@rollup/plugin-node-resolve";
|
||||
import sucrase from "@rollup/plugin-sucrase";
|
||||
import terser from "@rollup/plugin-terser";
|
||||
import { createHash } from "node:crypto";
|
||||
import license from "rollup-plugin-license";
|
||||
import { readFileSync } from "node:fs";
|
||||
import prettier from "prettier";
|
||||
|
||||
const pkg = JSON.parse(readFileSync("./package.json"));
|
||||
|
||||
const LICENSE_BANNER =
|
||||
"SPDX-License-Identifier: Unlicense\n" +
|
||||
"This file was automatically generated by https://github.com/yt-dlp/ejs" +
|
||||
"<% if (dependencies && dependencies.length) { %>" +
|
||||
"\n\nBundled Dependencies:" +
|
||||
"<% _.forEach(dependencies, function (dependency) { if (!dependency.private) { %>" +
|
||||
"\n\n---\nName: <%= dependency.name %>" +
|
||||
"<% if (dependency.version) { %>\nVersion: <%= dependency.version %><% } %>" +
|
||||
"\nLicense: <%= dependency.license %>" +
|
||||
"<% if (dependency.repository && dependency.repository.url) { %>\nRepository: <%= dependency.repository.url %><% } %>" +
|
||||
"<% if (dependency.homepage && dependency.homepage.url) { %>\nHomepage: <%= dependency.homepage.url %><% } %>" +
|
||||
"<% if (dependency.author) { %>\nAuthor: <%= dependency.author.text() %><% } %>" +
|
||||
"<% if (dependency.licenseText) { %>\n\n<%= dependency.licenseText %><% } %>" +
|
||||
"\n---<% } }) %>\n<% } %>";
|
||||
|
||||
function printHash() {
|
||||
return {
|
||||
name: "hash-output-plugin",
|
||||
writeBundle(_options, bundle) {
|
||||
for (const [fileName, assetInfo] of Object.entries(bundle)) {
|
||||
if (assetInfo.code) {
|
||||
try {
|
||||
const digest = createHash("sha3-512")
|
||||
.update(assetInfo.code)
|
||||
.digest("hex");
|
||||
console.log(`SHA3-512 for ${assetInfo.fileName}: ${digest}`);
|
||||
} catch (err) {
|
||||
console.error(`Error hashing ${fileName}:`, err.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function dynamicImportRewrite({ format = "deno" } = {}) {
|
||||
return {
|
||||
name: "dynamic-import-rewrite-plugin",
|
||||
resolveId(source) {
|
||||
if (pkg.dependencies[source]) {
|
||||
if (format === "deno") {
|
||||
return {
|
||||
id: `npm:${source}@${pkg.dependencies[source]}`,
|
||||
external: true,
|
||||
};
|
||||
} else if (format === "bun") {
|
||||
return {
|
||||
id: `${source}@${pkg.dependencies[source]}`,
|
||||
external: true,
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
renderDynamicImport() {
|
||||
return null;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function prettifyOutput() {
|
||||
return {
|
||||
name: "prettify-output",
|
||||
renderChunk(code) {
|
||||
return prettier.format(code, { parser: "babel", singleQuote: true });
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
input: "src/yt/solver/main.ts",
|
||||
output: {
|
||||
name: "jsc",
|
||||
globals: {
|
||||
astring: "astring",
|
||||
input: "input",
|
||||
meriyah: "meriyah",
|
||||
},
|
||||
file: "dist/yt.solver.core.js",
|
||||
format: "iife",
|
||||
},
|
||||
external: ["astring", "meriyah"],
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
sucrase({
|
||||
exclude: ["node_modules/**"],
|
||||
transforms: ["typescript"],
|
||||
}),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
// Use terser to remove comments but do not minify
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
}),
|
||||
prettifyOutput(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "src/yt/solver/main.ts",
|
||||
output: {
|
||||
name: "jsc",
|
||||
globals: {
|
||||
astring: "astring",
|
||||
input: "input",
|
||||
meriyah: "meriyah",
|
||||
},
|
||||
file: "dist/yt.solver.core.min.js",
|
||||
compact: true,
|
||||
format: "iife",
|
||||
minifyInternalExports: true,
|
||||
},
|
||||
external: ["astring", "meriyah"],
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
sucrase({
|
||||
exclude: ["node_modules/**"],
|
||||
transforms: ["typescript"],
|
||||
}),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
terser(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "src/yt/solver/lib.ts",
|
||||
output: {
|
||||
name: "lib",
|
||||
file: "dist/yt.solver.lib.js",
|
||||
format: "iife",
|
||||
exports: "named",
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
sucrase({
|
||||
exclude: ["node_modules/**"],
|
||||
transforms: ["typescript"],
|
||||
}),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
// Use terser to remove comments but do not minify
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
}),
|
||||
prettifyOutput(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "src/yt/solver/lib.ts",
|
||||
output: {
|
||||
name: "lib",
|
||||
file: "dist/yt.solver.lib.min.js",
|
||||
compact: true,
|
||||
format: "iife",
|
||||
minifyInternalExports: true,
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve(),
|
||||
sucrase({
|
||||
exclude: ["node_modules/**"],
|
||||
transforms: ["typescript"],
|
||||
}),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
terser(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "src/yt/solver/dynamic.lib.ts",
|
||||
output: {
|
||||
name: "lib",
|
||||
file: "dist/yt.solver.deno.lib.js",
|
||||
format: "es",
|
||||
},
|
||||
plugins: [
|
||||
dynamicImportRewrite(),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
// Use terser to remove comments but do not minify
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
}),
|
||||
prettifyOutput(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
{
|
||||
input: "src/yt/solver/dynamic.lib.ts",
|
||||
output: {
|
||||
name: "lib",
|
||||
file: "dist/yt.solver.bun.lib.js",
|
||||
format: "es",
|
||||
},
|
||||
plugins: [
|
||||
dynamicImportRewrite({ format: "bun" }),
|
||||
license({
|
||||
banner: {
|
||||
commentStyle: "ignored",
|
||||
content: LICENSE_BANNER,
|
||||
},
|
||||
}),
|
||||
// Use terser to remove comments but do not minify
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
}),
|
||||
prettifyOutput(),
|
||||
printHash(),
|
||||
],
|
||||
},
|
||||
]);
|
||||
21
src/types.ts
21
src/types.ts
@@ -1,7 +1,16 @@
|
||||
export type DeepPartial<T> = T extends object
|
||||
? Or<{
|
||||
[P in keyof T]?: DeepPartial<T[P]>;
|
||||
}>
|
||||
: Or<T>;
|
||||
type DP<T> = T extends (infer U)[]
|
||||
? DeepPartial<U>[]
|
||||
: T extends object
|
||||
? { [P in keyof T]?: DeepPartial<T[P]> }
|
||||
: T;
|
||||
|
||||
type Or<T> = T | { or: T[] };
|
||||
type ValueOf<T> = T extends (infer U)[]
|
||||
? U
|
||||
: T extends object
|
||||
? T[keyof T]
|
||||
: never;
|
||||
|
||||
export type DeepPartial<T> =
|
||||
| DP<T>
|
||||
| { or: DP<T>[] }
|
||||
| { anykey: DP<ValueOf<T>>[] };
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type ESTree } from "meriyah";
|
||||
import { parse, type ESTree } from "meriyah";
|
||||
import { type DeepPartial } from "./types.ts";
|
||||
|
||||
export function matchesStructure<T extends ESTree.Node>(
|
||||
@@ -42,3 +42,10 @@ export function matchesStructure<T extends ESTree.Node>(
|
||||
export function isOneOf<T>(value: unknown, ...of: readonly T[]): value is T {
|
||||
return of.includes(value as T);
|
||||
}
|
||||
|
||||
export function generateArrowFunction(
|
||||
data: string,
|
||||
): ESTree.ArrowFunctionExpression {
|
||||
return (parse(data).body[0] as ESTree.ExpressionStatement)
|
||||
.expression as ESTree.ArrowFunctionExpression;
|
||||
}
|
||||
|
||||
24
src/yt/solver/extract.ts
Normal file
24
src/yt/solver/extract.ts
Normal file
@@ -0,0 +1,24 @@
|
||||
import { parse } from "meriyah";
|
||||
import { getIO } from "./test/io.ts";
|
||||
import { downloadCached } from "./test/utils.ts";
|
||||
import { argv } from "node:process";
|
||||
import { getSolutions, modifyPlayer } from "./solvers.ts";
|
||||
import { generate } from "astring";
|
||||
|
||||
const data = await (
|
||||
argv.length > 3
|
||||
? () => downloadCached(argv[2], argv[3])
|
||||
: async () => {
|
||||
const io = await getIO();
|
||||
return await io.read(argv[2]);
|
||||
}
|
||||
)();
|
||||
|
||||
const program = parse(data);
|
||||
const statements = modifyPlayer(program);
|
||||
const solutionMap = getSolutions(statements);
|
||||
for (const solutions of Object.values(solutionMap)) {
|
||||
for (const solution of solutions) {
|
||||
console.log(String.raw`${generate(solution)}`);
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { parse } from "meriyah";
|
||||
import { generate } from "astring";
|
||||
|
||||
export const meriyah = { parse };
|
||||
export const astring = { generate };
|
||||
export const lib = {
|
||||
meriyah: { parse },
|
||||
astring: { generate },
|
||||
};
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
import { type ESTree } from "meriyah";
|
||||
import { matchesStructure } from "../../utils.ts";
|
||||
import { type DeepPartial } from "../../types.ts";
|
||||
|
||||
const identifier: DeepPartial<ESTree.VariableDeclaration> = {
|
||||
type: "VariableDeclaration",
|
||||
kind: "var",
|
||||
declarations: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
id: {
|
||||
type: "Identifier",
|
||||
},
|
||||
init: {
|
||||
type: "ArrayExpression",
|
||||
elements: [
|
||||
{
|
||||
type: "Identifier",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const catchBlockBody = [
|
||||
{
|
||||
type: "ReturnStatement",
|
||||
argument: {
|
||||
type: "BinaryExpression",
|
||||
left: {
|
||||
type: "MemberExpression",
|
||||
object: {
|
||||
type: "Identifier",
|
||||
},
|
||||
computed: true,
|
||||
property: {
|
||||
type: "Literal",
|
||||
},
|
||||
optional: false,
|
||||
},
|
||||
right: {
|
||||
type: "Identifier",
|
||||
},
|
||||
operator: "+",
|
||||
},
|
||||
},
|
||||
] as const;
|
||||
|
||||
export function extract(
|
||||
node: ESTree.Node,
|
||||
): ESTree.ArrowFunctionExpression | null {
|
||||
if (!matchesStructure(node, identifier)) {
|
||||
// Fallback search for try { } catch { return X[12] + Y }
|
||||
let name: string | undefined | null = null;
|
||||
let block: ESTree.BlockStatement | null | undefined = null;
|
||||
switch (node.type) {
|
||||
case "ExpressionStatement": {
|
||||
if (
|
||||
node.expression.type === "AssignmentExpression" &&
|
||||
node.expression.left.type === "Identifier" &&
|
||||
node.expression.right.type === "FunctionExpression" &&
|
||||
node.expression.right.params.length === 1
|
||||
) {
|
||||
name = node.expression.left.name;
|
||||
block = node.expression.right.body;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "FunctionDeclaration": {
|
||||
if (node.params.length === 1) {
|
||||
name = node.id?.name;
|
||||
block = node.body;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!block || !name) {
|
||||
return null;
|
||||
}
|
||||
const tryNode = block.body.at(-2);
|
||||
if (
|
||||
tryNode?.type !== "TryStatement" ||
|
||||
tryNode.handler?.type !== "CatchClause"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const catchBody = tryNode.handler!.body.body;
|
||||
if (matchesStructure(catchBody, catchBlockBody)) {
|
||||
return makeSolverFuncFromName(name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
if (node.type !== "VariableDeclaration") {
|
||||
return null;
|
||||
}
|
||||
const declaration = node.declarations[0];
|
||||
if (
|
||||
declaration.type !== "VariableDeclarator" ||
|
||||
!declaration.init ||
|
||||
declaration.init.type !== "ArrayExpression" ||
|
||||
declaration.init.elements.length !== 1
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const [firstElement] = declaration.init.elements;
|
||||
if (!firstElement || firstElement.type !== "Identifier") {
|
||||
return null;
|
||||
}
|
||||
return makeSolverFuncFromName(firstElement.name);
|
||||
}
|
||||
|
||||
function makeSolverFuncFromName(name: string): ESTree.ArrowFunctionExpression {
|
||||
return {
|
||||
type: "ArrowFunctionExpression",
|
||||
params: [
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "n",
|
||||
},
|
||||
],
|
||||
body: {
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
name: name,
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "n",
|
||||
},
|
||||
],
|
||||
optional: false,
|
||||
},
|
||||
async: false,
|
||||
expression: false,
|
||||
generator: false,
|
||||
};
|
||||
}
|
||||
143
src/yt/solver/nsig.ts
Normal file
143
src/yt/solver/nsig.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { type ESTree } from "meriyah";
|
||||
import { generate } from "astring";
|
||||
import { matchesStructure, generateArrowFunction } from "../../utils.ts";
|
||||
import { type DeepPartial } from "../../types.ts";
|
||||
|
||||
const identifier: DeepPartial<ESTree.Node> = {
|
||||
or: [
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
operator: "=",
|
||||
left: {
|
||||
or: [{ type: "Identifier" }, { type: "MemberExpression" }],
|
||||
},
|
||||
right: {
|
||||
type: "FunctionExpression",
|
||||
async: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "FunctionDeclaration",
|
||||
async: false,
|
||||
id: { type: "Identifier" },
|
||||
},
|
||||
{
|
||||
type: "VariableDeclaration",
|
||||
declarations: {
|
||||
anykey: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
init: {
|
||||
type: "FunctionExpression",
|
||||
async: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
} as const;
|
||||
|
||||
const asdasd: DeepPartial<ESTree.ExpressionStatement> = {
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "MemberExpression",
|
||||
object: { type: "Identifier" },
|
||||
property: {},
|
||||
optional: false,
|
||||
},
|
||||
arguments: [
|
||||
{
|
||||
type: "Literal",
|
||||
value: "alr",
|
||||
},
|
||||
{
|
||||
type: "Literal",
|
||||
value: "yes",
|
||||
},
|
||||
],
|
||||
optional: false,
|
||||
},
|
||||
};
|
||||
|
||||
export function extract(
|
||||
node: ESTree.Node,
|
||||
): ESTree.ArrowFunctionExpression | null {
|
||||
if (!matchesStructure(node, identifier)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const options: {
|
||||
name: ESTree.Expression;
|
||||
statements: ESTree.Statement[];
|
||||
}[] = [];
|
||||
|
||||
if (node.type === "FunctionDeclaration") {
|
||||
if (node.id && node.body?.body) {
|
||||
options.push({
|
||||
name: node.id,
|
||||
statements: node.body?.body,
|
||||
});
|
||||
}
|
||||
} else if (node.type === "ExpressionStatement") {
|
||||
if (node.expression.type !== "AssignmentExpression") {
|
||||
return null;
|
||||
}
|
||||
const name = node.expression.left;
|
||||
const body = (node.expression.right as ESTree.FunctionExpression)?.body
|
||||
?.body;
|
||||
if (name && body) {
|
||||
options.push({
|
||||
name: name,
|
||||
statements: body,
|
||||
});
|
||||
}
|
||||
} else if (node.type === "VariableDeclaration") {
|
||||
for (const declaration of node.declarations) {
|
||||
const name = declaration.id;
|
||||
const body = (declaration.init as ESTree.FunctionExpression)?.body?.body;
|
||||
if (name && body) {
|
||||
options.push({
|
||||
name: name,
|
||||
statements: body,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const { name, statements } of options) {
|
||||
if (matchesStructure(statements, { anykey: [asdasd] })) {
|
||||
return createSolver(name);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function createSolver(
|
||||
expression: ESTree.Expression,
|
||||
): ESTree.ArrowFunctionExpression {
|
||||
return generateArrowFunction(`
|
||||
({sig, n}) => {
|
||||
const url = (${generate(expression)})("https://youtube.com/watch?v=yt-dlp-wins", "s", sig ? encodeURIComponent(sig) : undefined);
|
||||
url.set("n", n);
|
||||
const proto = Object.getPrototypeOf(url);
|
||||
const keys = Object.keys(proto).concat(Object.getOwnPropertyNames(proto));
|
||||
for (const key of keys) {
|
||||
if (!["constructor", "set", "get", "clone"].includes(key)) {
|
||||
url[key]();
|
||||
break;
|
||||
}
|
||||
}
|
||||
const s = url.get("s");
|
||||
return {
|
||||
sig: s ? decodeURIComponent(s) : null,
|
||||
n: url.get("n") ?? null,
|
||||
};
|
||||
}
|
||||
`);
|
||||
}
|
||||
@@ -4,9 +4,8 @@ export const setupNodes = parse(`
|
||||
if (typeof globalThis.XMLHttpRequest === "undefined") {
|
||||
globalThis.XMLHttpRequest = { prototype: {} };
|
||||
}
|
||||
const window = Object.create(null);
|
||||
if (typeof URL === "undefined") {
|
||||
window.location = {
|
||||
globalThis.location = {
|
||||
hash: "",
|
||||
host: "www.youtube.com",
|
||||
hostname: "www.youtube.com",
|
||||
@@ -20,7 +19,7 @@ if (typeof URL === "undefined") {
|
||||
username: "",
|
||||
};
|
||||
} else {
|
||||
window.location = new URL("https://www.youtube.com/watch?v=yt-dlp-wins");
|
||||
globalThis.location = new URL("https://www.youtube.com/watch?v=yt-dlp-wins");
|
||||
}
|
||||
if (typeof globalThis.document === "undefined") {
|
||||
globalThis.document = Object.create(null);
|
||||
@@ -31,4 +30,7 @@ if (typeof globalThis.navigator === "undefined") {
|
||||
if (typeof globalThis.self === "undefined") {
|
||||
globalThis.self = globalThis;
|
||||
}
|
||||
if (typeof globalThis.window === "undefined") {
|
||||
globalThis.window = globalThis;
|
||||
}
|
||||
`).body;
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
import { type ESTree } from "meriyah";
|
||||
import { matchesStructure } from "../../utils.ts";
|
||||
import { type DeepPartial } from "../../types.ts";
|
||||
|
||||
const logicalExpression: DeepPartial<ESTree.ExpressionStatement> = {
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "LogicalExpression",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
},
|
||||
right: {
|
||||
type: "SequenceExpression",
|
||||
expressions: [
|
||||
{
|
||||
type: "AssignmentExpression",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
},
|
||||
operator: "=",
|
||||
right: {
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
},
|
||||
arguments: {
|
||||
or: [
|
||||
[
|
||||
{ type: "Literal" },
|
||||
{
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
name: "decodeURIComponent",
|
||||
},
|
||||
arguments: [{ type: "Identifier" }],
|
||||
optional: false,
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
name: "decodeURIComponent",
|
||||
},
|
||||
arguments: [{ type: "Identifier" }],
|
||||
optional: false,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
optional: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "CallExpression",
|
||||
},
|
||||
],
|
||||
},
|
||||
operator: "&&",
|
||||
},
|
||||
};
|
||||
|
||||
const identifier = {
|
||||
or: [
|
||||
{
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "Identifier",
|
||||
},
|
||||
right: {
|
||||
type: "FunctionExpression",
|
||||
params: [{}, {}, {}],
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
type: "FunctionDeclaration",
|
||||
params: [{}, {}, {}],
|
||||
},
|
||||
{
|
||||
type: "VariableDeclaration",
|
||||
declarations: {
|
||||
anykey: [
|
||||
{
|
||||
type: "VariableDeclarator",
|
||||
init: {
|
||||
type: "FunctionExpression",
|
||||
params: [{}, {}, {}],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
} as const;
|
||||
|
||||
export function extract(
|
||||
node: ESTree.Node,
|
||||
): ESTree.ArrowFunctionExpression | null {
|
||||
if (
|
||||
!matchesStructure(node, identifier as unknown as DeepPartial<ESTree.Node>)
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
let block: ESTree.BlockStatement | undefined | null;
|
||||
if (node.type === "ExpressionStatement" &&
|
||||
node.expression.type === "AssignmentExpression" &&
|
||||
node.expression.right.type === "FunctionExpression") {
|
||||
block = node.expression.right.body;
|
||||
} else if (node.type === "VariableDeclaration") {
|
||||
for (const decl of node.declarations) {
|
||||
if (
|
||||
decl.type === "VariableDeclarator" &&
|
||||
decl.init?.type === "FunctionExpression" &&
|
||||
decl.init?.params.length === 3
|
||||
) {
|
||||
block = decl.init.body;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (node.type === "FunctionDeclaration") {
|
||||
block = node.body;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
const relevantExpression = block?.body.at(-2);
|
||||
if (!matchesStructure(relevantExpression!, logicalExpression)) {
|
||||
return null;
|
||||
}
|
||||
if (
|
||||
relevantExpression?.type !== "ExpressionStatement" ||
|
||||
relevantExpression.expression.type !== "LogicalExpression" ||
|
||||
relevantExpression.expression.right.type !== "SequenceExpression" ||
|
||||
relevantExpression.expression.right.expressions[0].type !==
|
||||
"AssignmentExpression"
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
const call = relevantExpression.expression.right.expressions[0].right;
|
||||
if (call.type !== "CallExpression" || call.callee.type !== "Identifier") {
|
||||
return null;
|
||||
}
|
||||
// TODO: verify identifiers here
|
||||
return {
|
||||
type: "ArrowFunctionExpression",
|
||||
params: [
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "sig",
|
||||
},
|
||||
],
|
||||
body: {
|
||||
type: "CallExpression",
|
||||
callee: {
|
||||
type: "Identifier",
|
||||
name: call.callee.name,
|
||||
},
|
||||
arguments:
|
||||
call.arguments.length === 1
|
||||
? [
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "sig",
|
||||
},
|
||||
]
|
||||
: [
|
||||
call.arguments[0],
|
||||
{
|
||||
type: "Identifier",
|
||||
name: "sig",
|
||||
},
|
||||
],
|
||||
optional: false,
|
||||
},
|
||||
async: false,
|
||||
expression: false,
|
||||
generator: false,
|
||||
};
|
||||
}
|
||||
@@ -8,7 +8,7 @@ const io = await getIO();
|
||||
for (const test of tests) {
|
||||
for (const variant of test.variants ?? players.keys()) {
|
||||
const path = getCachePath(test.player, variant);
|
||||
await io.test(`${test.player} ${variant}`, async (assert, subtest) => {
|
||||
await io.test(`-${test.player}-${variant}-`, async (assert, subtest) => {
|
||||
const content = await io.read(path);
|
||||
const solvers = getFromPrepared(preprocessPlayer(content));
|
||||
for (const mode of ["n", "sig"] as const) {
|
||||
|
||||
@@ -1,14 +1,45 @@
|
||||
import { type ESTree, parse } from "meriyah";
|
||||
import { generate } from "astring";
|
||||
import { extract as extractSig } from "./sig.ts";
|
||||
import { extract as extractN } from "./n.ts";
|
||||
import { extract } from "./nsig.ts";
|
||||
import { setupNodes } from "./setup.ts";
|
||||
import { generateArrowFunction } from "../../utils.ts";
|
||||
|
||||
export function preprocessPlayer(data: string): string {
|
||||
const ast = parse(data);
|
||||
const body = ast.body;
|
||||
const program = parse(data);
|
||||
const plainStatements = modifyPlayer(program);
|
||||
const solutions = getSolutions(plainStatements);
|
||||
for (const [name, options] of Object.entries(solutions)) {
|
||||
plainStatements.push({
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "MemberExpression",
|
||||
computed: false,
|
||||
object: {
|
||||
type: "Identifier",
|
||||
name: "_result",
|
||||
},
|
||||
property: {
|
||||
type: "Identifier",
|
||||
name: name,
|
||||
},
|
||||
optional: false,
|
||||
},
|
||||
right: multiTry(options),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
const block = (() => {
|
||||
program.body.splice(0, 0, ...setupNodes);
|
||||
return generate(program);
|
||||
}
|
||||
|
||||
export function modifyPlayer(program: ESTree.Program) {
|
||||
const body = program.body;
|
||||
|
||||
const block: ESTree.BlockStatement = (() => {
|
||||
switch (body.length) {
|
||||
case 1: {
|
||||
const func = body[0];
|
||||
@@ -40,19 +71,7 @@ export function preprocessPlayer(data: string): string {
|
||||
throw "unexpected structure";
|
||||
})();
|
||||
|
||||
const found = {
|
||||
n: [] as ESTree.ArrowFunctionExpression[],
|
||||
sig: [] as ESTree.ArrowFunctionExpression[],
|
||||
};
|
||||
const plainExpressions = block.body.filter((node: ESTree.Node) => {
|
||||
const n = extractN(node);
|
||||
if (n) {
|
||||
found.n.push(n);
|
||||
}
|
||||
const sig = extractSig(node);
|
||||
if (sig) {
|
||||
found.sig.push(sig);
|
||||
}
|
||||
block.body = block.body.filter((node: ESTree.Statement) => {
|
||||
if (node.type === "ExpressionStatement") {
|
||||
if (node.expression.type === "AssignmentExpression") {
|
||||
return true;
|
||||
@@ -61,43 +80,75 @@ export function preprocessPlayer(data: string): string {
|
||||
}
|
||||
return true;
|
||||
});
|
||||
block.body = plainExpressions;
|
||||
|
||||
for (const [name, options] of Object.entries(found)) {
|
||||
// TODO: this is cringe fix plz
|
||||
const unique = new Set(options.map((x) => JSON.stringify(x)));
|
||||
if (unique.size !== 1) {
|
||||
const message = `found ${unique.size} ${name} function possibilities`;
|
||||
throw (
|
||||
message +
|
||||
(unique.size ? `: ${options.map((x) => generate(x)).join(", ")}` : "")
|
||||
return block.body;
|
||||
}
|
||||
|
||||
export function getSolutions(
|
||||
statements: ESTree.Statement[],
|
||||
): Record<string, ESTree.ArrowFunctionExpression[]> {
|
||||
const found = {
|
||||
n: [] as ESTree.ArrowFunctionExpression[],
|
||||
sig: [] as ESTree.ArrowFunctionExpression[],
|
||||
};
|
||||
for (const statement of statements) {
|
||||
const result = extract(statement);
|
||||
if (result) {
|
||||
found.n.push(
|
||||
makeSolver(result, {
|
||||
type: "Identifier",
|
||||
name: "n",
|
||||
}),
|
||||
);
|
||||
found.sig.push(
|
||||
makeSolver(result, {
|
||||
type: "Identifier",
|
||||
name: "sig",
|
||||
}),
|
||||
);
|
||||
}
|
||||
plainExpressions.push({
|
||||
type: "ExpressionStatement",
|
||||
expression: {
|
||||
type: "AssignmentExpression",
|
||||
operator: "=",
|
||||
left: {
|
||||
type: "MemberExpression",
|
||||
computed: false,
|
||||
object: {
|
||||
type: "Identifier",
|
||||
name: "_result",
|
||||
},
|
||||
property: {
|
||||
type: "Identifier",
|
||||
name: name,
|
||||
},
|
||||
},
|
||||
right: options[0],
|
||||
},
|
||||
});
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
ast.body.splice(0, 0, ...setupNodes);
|
||||
|
||||
return generate(ast);
|
||||
function makeSolver(
|
||||
result: ESTree.ArrowFunctionExpression,
|
||||
ident: ESTree.Identifier,
|
||||
): ESTree.ArrowFunctionExpression {
|
||||
return {
|
||||
type: "ArrowFunctionExpression",
|
||||
params: [ident],
|
||||
body: {
|
||||
type: "MemberExpression",
|
||||
object: {
|
||||
type: "CallExpression",
|
||||
callee: result,
|
||||
arguments: [
|
||||
{
|
||||
type: "ObjectExpression",
|
||||
properties: [
|
||||
{
|
||||
type: "Property",
|
||||
key: ident,
|
||||
value: ident,
|
||||
kind: "init",
|
||||
computed: false,
|
||||
method: false,
|
||||
shorthand: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
optional: false,
|
||||
},
|
||||
computed: false,
|
||||
property: ident,
|
||||
optional: false,
|
||||
},
|
||||
async: false,
|
||||
expression: true,
|
||||
generator: false,
|
||||
};
|
||||
}
|
||||
|
||||
export function getFromPrepared(code: string): {
|
||||
@@ -108,3 +159,31 @@ export function getFromPrepared(code: string): {
|
||||
Function("_result", code)(resultObj);
|
||||
return resultObj;
|
||||
}
|
||||
|
||||
function multiTry(
|
||||
generators: ESTree.ArrowFunctionExpression[],
|
||||
): ESTree.ArrowFunctionExpression {
|
||||
return generateArrowFunction(`
|
||||
(_input) => {
|
||||
const _results = new Set();
|
||||
const errors = [];
|
||||
for (const _generator of ${generate({
|
||||
type: "ArrayExpression",
|
||||
elements: generators,
|
||||
} as ESTree.Node)}) {
|
||||
try {
|
||||
_results.add(_generator(_input));
|
||||
} catch (e) {
|
||||
errors.push(e);
|
||||
}
|
||||
}
|
||||
if (!_results.size) {
|
||||
throw \`no solutions: \${errors.join(", ")}\`;
|
||||
}
|
||||
if (_results.size !== 1) {
|
||||
throw \`invalid solutions: \${[..._results].map(x => JSON.stringify(x)).join(", ")}\`;
|
||||
}
|
||||
return _results.values().next().value;
|
||||
}
|
||||
`);
|
||||
}
|
||||
|
||||
@@ -1,24 +1,13 @@
|
||||
import { players, tests } from "./tests.ts";
|
||||
import { getCachePath } from "./utils.ts";
|
||||
import { getIO } from "./io.ts";
|
||||
|
||||
const io = await getIO();
|
||||
import { downloadCached } from "./utils.ts";
|
||||
|
||||
for (const test of tests) {
|
||||
const variants = test.variants ?? players.keys();
|
||||
for (const variant of variants) {
|
||||
const path = getCachePath(test.player, variant);
|
||||
if (await io.exists(path)) {
|
||||
continue;
|
||||
try {
|
||||
await downloadCached(test.player, variant);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
const playerPath = players.get(variant);
|
||||
const url = `https://www.youtube.com/s/player/${test.player}/${playerPath}`;
|
||||
console.log("Requesting", url);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
console.error(`Failed to request ${variant} player for ${test.player}`);
|
||||
continue;
|
||||
}
|
||||
await io.write(path, response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,264 +10,103 @@ export const tests: {
|
||||
sig?: Step[];
|
||||
}[] = [
|
||||
{
|
||||
player: "3d3ba064",
|
||||
// 20522
|
||||
player: "74edf1a3",
|
||||
n: [
|
||||
{ input: "ZdZIqFPQK-Ty8wId", expected: "qmtUsIz04xxiNW" },
|
||||
{ input: "4GMrWHyKI5cEvhDO", expected: "N9gmEX7YhKTSmw" },
|
||||
{ input: "IlLiA21ny7gqA2m4p37", expected: "9nRTxrbM1f0yHg" },
|
||||
{ input: "eabGFpsUKuWHXGh6FR4", expected: "izmYqDEY6kl7Sg" },
|
||||
{ input: "eabGF/ps%UK=uWHXGh6FR4", expected: "LACmqlhaBpiPlgE-a" },
|
||||
],
|
||||
sig: [
|
||||
{
|
||||
input:
|
||||
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
|
||||
"NJAJEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyyPRt=BM8-XO5tm5hlMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=gwzz",
|
||||
expected:
|
||||
"ttJC2JfQdSswRAIgGBCxZyAfKyi0cjXCb3gqEctUw-NYdNmOEvaepit0zJAtIEsgOV2SXZjhSHMNy0NXNG_1kNyBf6HPuAuCduh-a7O",
|
||||
"NJAJEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyyPRt=BM8-XO5tm5hzMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=gwzl",
|
||||
},
|
||||
{
|
||||
input:
|
||||
"\x00\x01\x02%\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49",
|
||||
expected:
|
||||
"\x00\x01\x02%\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x40\x41\x42\x49\x44\x45\x46\x47\x48\x43",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "5ec65609",
|
||||
n: [{ input: "0eRGgQWJGfT5rFHFj", expected: "4SvMpDQH-vBJCw" }],
|
||||
// 20523
|
||||
player: "901741ab",
|
||||
n: [{ input: "BQoJvGBkC2nj1ZZLK-", expected: "UMPovvBZRh-sjb" }],
|
||||
sig: [
|
||||
{
|
||||
input:
|
||||
"AAJAJfQdSswRQIhAMG5SN7-cAFChdrE7tLA6grH0rTMICA1mmDc0HoXgW3CAiAQQ4=CspfaF_vt82XH5yewvqcuEkvzeTsbRuHssRMyJQ=I",
|
||||
"NJAJEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyyPRt=BM8-XO5tm5hlMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=gwzz",
|
||||
expected:
|
||||
"AJfQdSswRQIhAMG5SN7-cAFChdrE7tLA6grI0rTMICA1mmDc0HoXgW3CAiAQQ4HCspfaF_vt82XH5yewvqcuEkvzeTsbRuHssRMyJQ==",
|
||||
"wgwCHlydB9Hg7PMegXoVzaoAXXB8woPSNZqRUC3Pe7vAEiApVSCMlhwmt5ON-8MB=5RPyyzdAM9MPM-kPfjgTxEK0IAhIgRwE0jiEJA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "6742b2b9",
|
||||
n: [
|
||||
{ input: "_HPB-7GFg1VTkn9u", expected: "qUAsPryAO_ByYg" },
|
||||
{ input: "K1t_fcB6phzuq2SF", expected: "Y7PcOt3VE62mog" },
|
||||
],
|
||||
// 20524
|
||||
player: "e7573094",
|
||||
n: [{ input: "IlLiA21ny7gqA2m4p37", expected: "3KuQ3235dojTSjo4" }],
|
||||
sig: [
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"NJAJEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyyPRt=BM8-XO5tm5hlMCSVpAiEAv7eP3CURqZNSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=gwzz",
|
||||
expected:
|
||||
"AJfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYu7S6SHM8EjoCACIEQnz-nKN5RgG6iUTnNJC58csYPSrnS_SzricuUMJZGM",
|
||||
"yEij0EwRgIhAI0KExTgjfPk-MPM9MAdzyNPRt=BM8-XO5tm5hlMCSVNAiEAvpeP3CURqZJSPow8BXXAoazVoXgeMP7gH9BdylHCwgw=g",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "23ccdd25",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "orSsTqUaUO-j" },
|
||||
],
|
||||
// 20525
|
||||
player: "9fcf08e8",
|
||||
n: [{ input: "4JRSxxN0E_fLVnxmd", expected: "xhAoMP8xPcR5wg" }],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a",
|
||||
expected:
|
||||
"ZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hAU6wbTvorvVVMgIARwsSdQfJAN",
|
||||
"\x6a\x69\x68\x67\x66\x65\x64\x63\x62\x61\x60\x5f\x5e\x5d\x5c\x5b\x5a\x59\x58\x57\x56\x55\x54\x53\x52\x51\x50\x4f\x4e\x4d\x4c\x4b\x4a\x49\x48\x47\x46\x45\x44\x43\x42\x41\x40\x3f\x3e\x3d\x3c\x3b\x3a\x39\x38\x37\x36\x35\x34\x33\x32\x31\x30\x2f\x2e\x2d\x2c\x2b\x2a\x29\x28\x27\x26\x25\x24\x23\x22\x21\x20\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18\x17\x16\x15\x14\x13\x12\x11\x10\x0f\x0e\x0d\x0c\x0b\x03\x09\x08\x07\x06\x05\x04\x0a",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "3597727b",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "PRwo5dDfisg0ejA2" },
|
||||
],
|
||||
// 20527
|
||||
player: "21cd2156",
|
||||
n: [{ input: "16EF3jx-Mr_TLuGH", expected: "OQJDc7IrlWCkfg" }],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a",
|
||||
expected:
|
||||
"AAJfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYuMS6SHM8Ej7CACIEQnz-nKN5RgG6iUTnNJC58csYPSroS_SzricuUMJZG",
|
||||
"\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x00\x46\x47\x48\x49\x4a\x4b\x6a\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x4c",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "3752a005",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
// 20528 (tv & tv_es6 needed self.location.origin fix)
|
||||
player: "76ad2fe8",
|
||||
n: [{ input: "V8pdMGD0Sz_M0DRT", expected: "rBnTGCWGFpwByA" }],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"\x46\x66\x65\x64\x63\x62\x61\x60\x5f\x5e\x67\x6a\x5b\x5a\x59\x58\x57\x56\x55\x54\x53\x52\x51\x50\x4f\x4e\x4d\x4c\x4b\x4a\x49\x48\x47\x2c\x45\x44\x43\x42\x41\x40\x3f\x3e\x3d\x3c\x3b\x3a\x39\x38\x13\x36\x35\x34\x33\x32\x31\x30\x2f\x2e\x2d\x5d\x2b\x2a\x29\x28\x27\x26\x25\x24\x23\x22\x21\x20\x1f\x1e\x1d\x1c\x1b\x1a\x19\x18\x17\x16\x15\x14\x0c\x12\x11\x10\x0f\x0e\x0d\x00\x0b\x0a\x09\x08\x07\x06\x05\x04\x03\x02\x01\x37",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "afc7785b",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
// 20529 (tv & tv_es6 needed self.location.origin fix)
|
||||
player: "631d3938",
|
||||
n: [{ input: "KBx1qz7jMhxELa8c", expected: "ttPvh7WIptsgSw" }],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "b9645327",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// tce causes exception even in browser
|
||||
player: "035b9195",
|
||||
variants: ["main", "tcc", "es5", "es6", "tv", "tv_es6", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "j22ZtsqVsR0Dn" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJM_ucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHG6S7uYq4TGjQXSD4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "6740c111",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "AVsXYE0uE1k8e" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYu7S6SHM8EjoCACIEQnz-MKN5RgG6iUTnNJC58csYPSrnS_SzricuUMJZGn",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "f6a4f3bc",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "H1NKYFbhlqZ" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYM7S6SHM8EjoCACIEQnz-nKM5RgG6iUTnNJC58cNYPSrnS_SzricuUMJZGu",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "b66835e2",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "H1NKYFbhlqZ" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"JfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYM7S6SHM8EjoCACIEQnz-nKM5RgG6iUTnNJC58cNYPSrnS_SzricuUMJZGu",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "4f8fa943",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "JWWr7hDSRpMq5" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"AAJfQdSswRAIgMVVvrovTbw6UNh99kPa4D_XQjGT4qYu7S6SHr8EjoCACIEQnz-nKN5RgG6iUTnNZC58csYPSMnS_SzricuUM",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
player: "0004de42",
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "OPd7UEsCDmCw4qD0" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJAA",
|
||||
expected:
|
||||
"ZJMUucirzS_SnrSPYsc85MJNnTUi6GgR5NCn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQ",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// TODO: es6/tv_es6 variants currently fail
|
||||
player: "2b83d2e0",
|
||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "0eRGgQWJGfT5rFHFj", expected: "euHbygrCMLksxd" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"MMGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKn-znQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJA",
|
||||
expected:
|
||||
"-MGZJMUucirzS_SnrSPYsc85CJNnTUi6GgR5NKnMznQEICACojE8MHS6S7uYq4TGjQX_D4aPk99hNU6wbTvorvVVMgIARwsSdQfJ",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
// TODO: es6/tv_es6 variants currently fail
|
||||
player: "638ec5c6",
|
||||
variants: ["main", "tcc", "tce", "es5", "tv", "phone", "tablet"],
|
||||
n: [
|
||||
// Synthetic test
|
||||
{ input: "ZdZIqFPQK-Ty8wId", expected: "1qov8-KM-yH" },
|
||||
],
|
||||
sig: [
|
||||
// Synthetic test
|
||||
{
|
||||
input:
|
||||
"gN7a-hudCuAuPH6fByOk1_GNXN0yNMHShjZXS2VOgsEItAJz0tipeavEOmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
|
||||
expected:
|
||||
"MhudCuAuP-6fByOk1_GNXN7gNHHShjyXS2VOgsEItAJz0tipeav0OmNdYN-wUtcEqD3bCXjc0iyKfAyZxCBGgIARwsSdQfJ2CJtt",
|
||||
"\x19\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x00\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63",
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -277,12 +116,12 @@ export const players = new Map([
|
||||
["main", "player_ias.vflset/en_US/base.js"],
|
||||
["tcc", "player_ias_tcc.vflset/en_US/base.js"],
|
||||
["tce", "player_ias_tce.vflset/en_US/base.js"],
|
||||
["es5", "player_es5.vflset/en_US/base.js"],
|
||||
["es6", "player_es6.vflset/en_US/base.js"],
|
||||
["tv", "tv-player-ias.vflset/tv-player-ias.js"],
|
||||
["tv_es6", "tv-player-es6.vflset/tv-player-es6.js"],
|
||||
["phone", "player-plasma-ias-phone-en_US.vflset/base.js"],
|
||||
["tablet", "player-plasma-ias-tablet-en_US.vflset/base.js"],
|
||||
["es6_tcc", "player_es6_tcc.vflset/en_US/base.js"],
|
||||
["es6_tce", "player_es6_tce.vflset/en_US/base.js"],
|
||||
] as const);
|
||||
|
||||
export type Variant = typeof players extends Map<infer T, unknown> ? T : never;
|
||||
|
||||
@@ -1,5 +1,26 @@
|
||||
import { type Variant } from "./tests.ts";
|
||||
import { getIO } from "./io.ts";
|
||||
import { players, type Variant } from "./tests.ts";
|
||||
|
||||
export function getCachePath(player: string, variant: Variant) {
|
||||
return `src/yt/solver/test/players/${player}-${variant}`;
|
||||
}
|
||||
|
||||
export async function downloadCached(player: string, variant: string) {
|
||||
const io = await getIO();
|
||||
|
||||
const playerPath = players.get(variant as Variant);
|
||||
if (!playerPath) {
|
||||
throw `Invalid player variant: ${variant}`;
|
||||
}
|
||||
const path = getCachePath(player, variant as Variant);
|
||||
if (!(await io.exists(path))) {
|
||||
const url = `https://www.youtube.com/s/player/${player}/${playerPath}`;
|
||||
console.log("Requesting", url);
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw `Failed to request ${variant} player for ${player}`;
|
||||
}
|
||||
await io.write(path, response);
|
||||
}
|
||||
return await io.read(path);
|
||||
}
|
||||
|
||||
@@ -7,11 +7,15 @@ def core() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript core solver bundle as string.
|
||||
"""
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "core.min.js").read_text()
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "core.min.js").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
|
||||
def lib() -> str:
|
||||
"""
|
||||
Read the contents of the JavaScript library solver bundle as string.
|
||||
"""
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "lib.min.js").read_text()
|
||||
return (importlib.resources.files(yt_dlp_ejs.yt.solver) / "lib.min.js").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user