diff --git a/.github/workflows/demos_check.yml b/.github/workflows/demos_check.yml index 0d1dd7e9a..ab18f9dfb 100644 --- a/.github/workflows/demos_check.yml +++ b/.github/workflows/demos_check.yml @@ -1,6 +1,7 @@ name: demos lint on: + workflow_dispatch: {} push: branches: [master] paths: @@ -24,28 +25,24 @@ jobs: with: submodules: "true" + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + - name: Setup Node.js - uses: actions/setup-node@v2 + uses: actions/setup-node@v4 with: node-version: "20" - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - ${{ runner.os }}- - - name: Install project dependencies working-directory: ./demos - run: npm ci + run: pnpm install --frozen-lockfile - name: Lint code working-directory: ./demos - run: npm run lint + run: pnpm run lint - name: Typecheck code working-directory: ./demos - run: npm run typecheck + run: pnpm run typecheck diff --git a/.github/workflows/deploy_docs.yml b/.github/workflows/deploy_docs.yml index 8956a12d3..487bad26a 100644 --- a/.github/workflows/deploy_docs.yml +++ b/.github/workflows/deploy_docs.yml @@ -2,13 +2,6 @@ name: deploy to gh-pages on: workflow_dispatch: {} - push: - branches: [master] - paths: - - "docs/**" - - "schemas/**" - - "generate/src/bin/generate_from_types/**" - - ".github/workflows/deploy_docs.yml" permissions: contents: write diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 5772cde4f..c886e4242 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,5 +1,6 @@ name: lint on: + workflow_dispatch: {} push: branches: [master] pull_request: @@ -29,6 +30,11 @@ jobs: with: components: rustfmt, clippy + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + - name: 🛠 Setup Node.JS uses: actions/setup-node@v4 with: diff --git a/.github/workflows/macos_lint.yml b/.github/workflows/macos_lint.yml index 66b034242..59ca596ec 100644 --- a/.github/workflows/macos_lint.yml +++ b/.github/workflows/macos_lint.yml @@ -1,5 +1,6 @@ name: macos lint on: + workflow_dispatch: {} push: branches: [master] pull_request: diff --git a/.github/workflows/shellcheck.yml b/.github/workflows/shellcheck.yml index b30a5cd92..c0d791868 100644 --- a/.github/workflows/shellcheck.yml +++ b/.github/workflows/shellcheck.yml @@ -1,5 +1,6 @@ name: shellcheck on: + workflow_dispatch: {} push: branches: [master] paths: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 36a91fd60..e3938507a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,5 +1,6 @@ name: build and test on: + workflow_dispatch: {} push: branches: [master] pull_request: diff --git a/.github/workflows/ts_sdk_check.yml b/.github/workflows/ts_sdk_check.yml index f784491db..ee47a9e26 100644 --- a/.github/workflows/ts_sdk_check.yml +++ b/.github/workflows/ts_sdk_check.yml @@ -1,14 +1,11 @@ name: TS SDK check on: + workflow_dispatch: {} push: branches: [master] - paths: - - "ts/**" pull_request: types: [opened, synchronize] - paths: - - "ts/**" concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -22,32 +19,33 @@ jobs: - name: Checkout repo uses: actions/checkout@v2 - - name: Setup Node.js - uses: actions/setup-node@v2 + - name: 🔧 Install the rust toolchain + uses: dtolnay/rust-toolchain@stable with: - node-version: "20" + toolchain: 1.81.0 + + - name: Install pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 - - name: Cache dependencies - uses: actions/cache@v2 + - name: Setup Node.js + uses: actions/setup-node@v4 with: - path: ~/.npm - key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-node- - ${{ runner.os }}- + node-version: "20" - name: Install project dependencies working-directory: ./ts - run: npm install + run: pnpm install --frozen-lockfile - name: Build working-directory: ./ts - run: npm run build:all + run: pnpm run build:all - name: Lint code working-directory: ./ts - run: npm run lint + run: pnpm run lint - name: Typecheck code working-directory: ./ts - run: npm run typecheck + run: pnpm run typecheck diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index 844ea4253..791b49e46 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -1,5 +1,6 @@ name: wasm build on: + workflow_dispatch: {} push: branches: [master] pull_request: diff --git a/.vscode/settings.json b/.vscode/settings.json index 0348ca7fe..3684f4007 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,5 +7,13 @@ "url": "./schemas/scene.schema.json" } ], - "eslint.workingDirectories": [{ "mode": "auto" }] + "eslint.workingDirectories": [ + { "directory": "./demos", "changeProcessCWD": true }, + { "directory": "./ts", "changeProcessCWD": true }, + { "directory": "./docs", "changeProcessCWD": true } + ], + "prettier.requireConfig": true, + "prettier.configPath": "", + "editor.formatOnSave": true, + "editor.defaultFormatter": "esbenp.prettier-vscode" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 94d6e3d8c..24cf8e270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ ### ✨ New features - Add `loop` option for MP4 input. ([#699](https://github.com/software-mansion/live-compositor/pull/699) by [@WojciechBarczynski](https://github.com/WojciechBarczynski)) +- Add `LIVE_COMPOSITOR_LOG_FILE` environment variable to enable logging to file ([#853](https://github.com/software-mansion/live-compositor/pull/853) by [@wkozyra95](https://github.com/wkozyra95)) +- Add border, border radius and box shadow options to `Rescaler` and `View` components. ([#815](https://github.com/software-mansion/live-compositor/pull/815) by [@WojciechBarczynski](https://github.com/WojciechBarczynski), ([#839](https://github.com/software-mansion/live-compositor/pull/839), [#842](https://github.com/software-mansion/live-compositor/pull/842), [#858](https://github.com/software-mansion/live-compositor/pull/858) by [@wkozyra95](https://github.com/wkozyra95)) + ### 🐛 Bug fixes diff --git a/Cargo.lock b/Cargo.lock index 62f8d87a7..e5ff190e0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,22 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ab_glyph" +version = "0.2.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3672c180e71eeaaac3a541fbbc5f5ad4def8b747c595ad30d674e43049f7b0" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" + [[package]] name = "addr2line" version = "0.20.0" @@ -59,6 +75,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -79,6 +96,33 @@ version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" +[[package]] +name = "android-activity" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" +dependencies = [ + "android-properties", + "bitflags 2.6.0", + "cc", + "cesu8", + "jni", + "jni-sys", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "android-properties" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -103,6 +147,55 @@ dependencies = [ "winapi", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys 0.59.0", +] + [[package]] name = "anyhow" version = "1.0.72" @@ -136,6 +229,12 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "as-raw-xcb-connection" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b" + [[package]] name = "ascii" version = "1.1.0" @@ -472,6 +571,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae85a0696e7ea3b835a453750bf002770776609115e6d25c6d2ff28a8200f7e7" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys", + "objc2", +] + [[package]] name = "bumpalo" version = "3.13.0" @@ -480,9 +598,9 @@ checksum = "a3e2c3daef883ecc1b5d58c15adae93470a91d425f3532ba1695849656af3fc1" [[package]] name = "bytemuck" -version = "1.13.1" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17febce684fd15d89027105661fec94afb475cb995fbc59d2865198446ba2eea" +checksum = "8b37c88a63ffd85d15b406896cc343916d7cf57838a847b3a6f2ca5d39a5695a" dependencies = [ "bytemuck_derive", ] @@ -510,6 +628,32 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89b2fd2a0dcf38d7971e2194b6b6eebab45ae01067456a7fd93d5547a61b70be" +[[package]] +name = "calloop" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" +dependencies = [ + "bitflags 2.6.0", + "log", + "polling", + "rustix", + "slab", + "thiserror", +] + +[[package]] +name = "calloop-wayland-source" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f0ea9b9476c7fad82841a8dbb380e2eae480c21910feba80725b46931ed8f02" +dependencies = [ + "calloop", + "rustix", + "wayland-backend", + "wayland-client", +] + [[package]] name = "cbc" version = "0.1.2" @@ -541,6 +685,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + [[package]] name = "cexpr" version = "0.6.0" @@ -618,6 +768,46 @@ dependencies = [ "libloading 0.7.4", ] +[[package]] +name = "clap" +version = "4.5.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.75", +] + +[[package]] +name = "clap_lex" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7" + [[package]] name = "cmake" version = "0.1.50" @@ -643,6 +833,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "com" version = "0.6.0" @@ -674,6 +870,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + [[package]] name = "compositor_api" version = "0.1.0" @@ -782,6 +988,15 @@ dependencies = [ "wgpu", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console_error_panic_hook" version = "0.1.7" @@ -814,6 +1029,19 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" +[[package]] +name = "core-graphics" +version = "0.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + [[package]] name = "core-graphics-types" version = "0.1.3" @@ -962,6 +1190,12 @@ dependencies = [ "cipher", ] +[[package]] +name = "cursor-icon" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991" + [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -1136,6 +1370,12 @@ dependencies = [ "subtle", ] +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + [[package]] name = "displaydoc" version = "0.2.5" @@ -1147,6 +1387,15 @@ dependencies = [ "syn 2.0.75", ] +[[package]] +name = "dlib" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412" +dependencies = [ + "libloading 0.8.0", +] + [[package]] name = "document-features" version = "0.2.10" @@ -1156,6 +1405,12 @@ dependencies = [ "litrs", ] +[[package]] +name = "downcast-rs" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" + [[package]] name = "dyn-clone" version = "1.0.14" @@ -1598,6 +1853,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "gethostname" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818" +dependencies = [ + "libc", + "windows-targets 0.48.1", +] + [[package]] name = "getrandom" version = "0.2.10" @@ -1763,7 +2028,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.0.1", + "indexmap 2.6.0", "slab", "tokio", "tokio-util", @@ -1773,7 +2038,7 @@ dependencies = [ [[package]] name = "h264-reader" version = "0.7.1-dev" -source = "git+https://github.com/membraneframework-labs/h264-reader.git?branch=@jerzywilczek/scaling-lists#7c982f1089558640021ff8a70a2fa253e3e881c7" +source = "git+https://github.com/membraneframework-labs/h264-reader.git?branch=live-compositor#9292ad0ab24b75e07815f546f41cef24b30b09c9" dependencies = [ "bitstream-io", "hex-slice", @@ -1807,6 +2072,12 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + [[package]] name = "hassle-rs" version = "0.11.0" @@ -1822,12 +2093,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "443144c8cdadd93ebf52ddb4056d257f5b52c04d3c804e657d19eb73fc33668b" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "hex" version = "0.4.3" @@ -2007,6 +2290,17 @@ dependencies = [ "cc", ] +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2", + "dispatch", + "objc2", +] + [[package]] name = "idna" version = "0.5.0" @@ -2055,12 +2349,12 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.0.1" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad227c3af19d4914570ad36d30409928b75967c298feb9ea1969db3a610bb14e" +checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown 0.15.2", ] [[package]] @@ -2133,6 +2427,12 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itertools" version = "0.12.1" @@ -2148,6 +2448,22 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror", + "walkdir", + "windows-sys 0.45.0", +] + [[package]] name = "jni-sys" version = "0.3.0" @@ -2257,6 +2573,17 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.6.0", + "libc", + "redox_syscall 0.5.7", +] + [[package]] name = "link-cplusplus" version = "1.0.9" @@ -2529,7 +2856,7 @@ dependencies = [ "cfg_aliases 0.1.1", "codespan-reporting", "hexf-parse", - "indexmap 2.0.1", + "indexmap 2.6.0", "log", "rustc-hash 1.1.0", "spirv", @@ -2593,6 +2920,27 @@ dependencies = [ "tempfile", ] +[[package]] +name = "ndk" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" +dependencies = [ + "bitflags 2.6.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + [[package]] name = "ndk-sys" version = "0.5.0+25.2.9519653" @@ -2712,10 +3060,31 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.2", "libc", ] +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.75", +] + [[package]] name = "objc" version = "0.2.7" @@ -2725,6 +3094,28 @@ dependencies = [ "malloc_buf", ] +[[package]] +name = "objc-sys" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "object" version = "0.31.1" @@ -2809,6 +3200,15 @@ dependencies = [ "libc", ] +[[package]] +name = "orbclient" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba0b26cec2e24f08ed8bb31519a9333140a6599b867dac464bb150bdb796fd43" +dependencies = [ + "libredox", +] + [[package]] name = "overload" version = "0.1.1" @@ -2816,7 +3216,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] -name = "p256" +name = "owned_ttf_parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec719bbf3b2a81c109a4e20b1f129b5566b7dce654bc3872f6a05abf82b2c4" +dependencies = [ + "ttf-parser 0.25.0", +] + +[[package]] +name = "p256" version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" @@ -2857,7 +3266,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", "windows-targets 0.48.1", ] @@ -2975,6 +3384,21 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "polling" +version = "3.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "pollster" version = "0.3.0" @@ -3045,6 +3469,15 @@ dependencies = [ "elliptic-curve", ] +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -3069,6 +3502,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "quick-xml" +version = "0.36.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7649a7b4df05aed9ea7ec6f628c67c9953a43869b8bc50929569b2999d443fe" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.36" @@ -3202,6 +3644,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "regex" version = "1.10.6" @@ -3309,7 +3760,7 @@ dependencies = [ "png", "rgb", "svgtypes", - "tiny-skia", + "tiny-skia 0.10.0", "usvg", ] @@ -3586,6 +4037,15 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.22" @@ -3618,6 +4078,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + [[package]] name = "scopeguard" version = "1.2.0" @@ -3630,6 +4096,19 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" +[[package]] +name = "sctk-adwaita" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b31447ca297092c5a9916fc3b955203157b37c19ca8edde4f52e9843e602c7" +dependencies = [ + "ab_glyph", + "log", + "memmap2 0.9.4", + "smithay-client-toolkit", + "tiny-skia 0.11.4", +] + [[package]] name = "sdp" version = "0.6.2" @@ -3739,7 +4218,7 @@ version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" dependencies = [ - "indexmap 2.0.1", + "indexmap 2.6.0", "itoa", "ryu", "serde", @@ -3914,6 +4393,31 @@ version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +[[package]] +name = "smithay-client-toolkit" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" +dependencies = [ + "bitflags 2.6.0", + "calloop", + "calloop-wayland-source", + "cursor-icon", + "libc", + "log", + "memmap2 0.9.4", + "rustix", + "thiserror", + "wayland-backend", + "wayland-client", + "wayland-csd-frame", + "wayland-cursor", + "wayland-protocols", + "wayland-protocols-wlr", + "wayland-scanner", + "xkeysym", +] + [[package]] name = "smol_str" version = "0.2.2" @@ -3982,6 +4486,12 @@ dependencies = [ "float-cmp", ] +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + [[package]] name = "stun" version = "0.6.0" @@ -4141,7 +4651,7 @@ checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "redox_syscall 0.3.5", "rustix", "windows-sys 0.48.0", ] @@ -4239,7 +4749,21 @@ dependencies = [ "cfg-if", "log", "png", - "tiny-skia-path", + "tiny-skia-path 0.10.0", +] + +[[package]] +name = "tiny-skia" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83d13394d44dae3207b52a326c0c85a8bf87f1541f23b0d143811088497b09ab" +dependencies = [ + "arrayref", + "arrayvec", + "bytemuck", + "cfg-if", + "log", + "tiny-skia-path 0.11.4", ] [[package]] @@ -4253,6 +4777,17 @@ dependencies = [ "strict-num", ] +[[package]] +name = "tiny-skia-path" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c9e7fc0c2e86a30b117d0462aa261b72b7a99b7ebd7deb3a14ceda95c5bdc93" +dependencies = [ + "arrayref", + "bytemuck", + "strict-num", +] + [[package]] name = "tiny_http" version = "0.12.0" @@ -4357,6 +4892,23 @@ dependencies = [ "tracing", ] +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.22.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" +dependencies = [ + "indexmap 2.6.0", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -4544,6 +5096,12 @@ version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c591d83f69777866b9126b24c6dd9a18351f177e49d625920d19f989fd31cf8" +[[package]] +name = "ttf-parser" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5902c5d130972a0000f60860bfbf46f7ca3db5391eddfedd1b8728bd9dc96c0e" + [[package]] name = "tungstenite" version = "0.21.0" @@ -4768,7 +5326,7 @@ dependencies = [ "rctree", "strict-num", "svgtypes", - "tiny-skia-path", + "tiny-skia-path 0.10.0", ] [[package]] @@ -4777,6 +5335,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "uuid" version = "1.10.0" @@ -4820,7 +5384,10 @@ name = "vk-video" version = "0.1.0" dependencies = [ "ash", + "bytemuck", + "bytes", "cfg_aliases 0.2.1", + "clap", "derivative", "h264-reader", "thiserror", @@ -4828,6 +5395,7 @@ dependencies = [ "tracing-subscriber 0.3.18", "vk-mem", "wgpu", + "winit", ] [[package]] @@ -4839,6 +5407,16 @@ dependencies = [ "atomic-waker", ] +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" @@ -4932,6 +5510,115 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wayland-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "056535ced7a150d45159d3a8dc30f91a2e2d588ca0b23f70e56033622b8016f6" +dependencies = [ + "cc", + "downcast-rs", + "rustix", + "scoped-tls", + "smallvec", + "wayland-sys", +] + +[[package]] +name = "wayland-client" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66249d3fc69f76fd74c82cc319300faa554e9d865dab1f7cd66cc20db10b280" +dependencies = [ + "bitflags 2.6.0", + "rustix", + "wayland-backend", + "wayland-scanner", +] + +[[package]] +name = "wayland-csd-frame" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" +dependencies = [ + "bitflags 2.6.0", + "cursor-icon", + "wayland-backend", +] + +[[package]] +name = "wayland-cursor" +version = "0.31.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b08bc3aafdb0035e7fe0fdf17ba0c09c268732707dca4ae098f60cb28c9e4c" +dependencies = [ + "rustix", + "wayland-client", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.31.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-plasma" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-protocols-wlr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" +dependencies = [ + "bitflags 2.6.0", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-scanner", +] + +[[package]] +name = "wayland-scanner" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597f2001b2e5fc1121e3d5b9791d3e78f05ba6bfa4641053846248e3a13661c3" +dependencies = [ + "proc-macro2", + "quick-xml", + "quote", +] + +[[package]] +name = "wayland-sys" +version = "0.31.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efa8ac0d8e8ed3e3b5c9fc92c7881406a268e11555abe36493efabe649a29e09" +dependencies = [ + "dlib", + "log", + "once_cell", + "pkg-config", +] + [[package]] name = "web-sys" version = "0.3.70" @@ -4942,6 +5629,16 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web-time" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa30049b1c872b72c89866d458eae9f20380ab280ffd1b1e18df2d3e2d98cfe0" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "webrtc" version = "0.11.0" @@ -5213,7 +5910,7 @@ dependencies = [ "bitflags 2.6.0", "cfg_aliases 0.1.1", "document-features", - "indexmap 2.0.1", + "indexmap 2.6.0", "log", "naga", "once_cell", @@ -5412,6 +6109,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" @@ -5430,6 +6136,30 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + [[package]] name = "windows-targets" version = "0.48.1" @@ -5461,6 +6191,12 @@ dependencies = [ "windows_x86_64_msvc 0.52.6", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.0" @@ -5479,6 +6215,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cffbe740121affb56fad0fc0e421804adf0ae00891205213b5cecd30db881d" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.0" @@ -5497,6 +6239,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2564fde759adb79129d9b4f54be42b32c89970c18ebf93124ca8870a498688ed" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.0" @@ -5521,6 +6269,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cd9d32ba70453522332c14d38814bceeb747d80b3958676007acadd7e166956" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.0" @@ -5539,6 +6293,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfce6deae227ee8d356d19effc141a509cc503dfd1f850622ec4b0f84428e1f4" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.0" @@ -5551,6 +6311,12 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.0" @@ -5569,6 +6335,12 @@ version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d19538ccc21819d01deaf88d6a17eae6596a12e9aafdbb97916fb49896d89de9" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.0" @@ -5581,6 +6353,95 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winit" +version = "0.29.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d59ad965a635657faf09c8f062badd885748428933dad8e8bdd64064d92e5ca" +dependencies = [ + "ahash", + "android-activity", + "atomic-waker", + "bitflags 2.6.0", + "bytemuck", + "calloop", + "cfg_aliases 0.1.1", + "core-foundation", + "core-graphics", + "cursor-icon", + "icrate", + "js-sys", + "libc", + "log", + "memmap2 0.9.4", + "ndk", + "ndk-sys", + "objc2", + "once_cell", + "orbclient", + "percent-encoding", + "raw-window-handle", + "redox_syscall 0.3.5", + "rustix", + "sctk-adwaita", + "smithay-client-toolkit", + "smol_str", + "unicode-segmentation", + "wasm-bindgen", + "wasm-bindgen-futures", + "wayland-backend", + "wayland-client", + "wayland-protocols", + "wayland-protocols-plasma", + "web-sys", + "web-time", + "windows-sys 0.48.0", + "x11-dl", + "x11rb", + "xkbcommon-dl", +] + +[[package]] +name = "winnow" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36c1fec1a2bb5866f07c25f68c26e565c4c200aebb96d7e55710c19d3e8ac49b" +dependencies = [ + "memchr", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d91ffca73ee7f68ce055750bf9f6eca0780b8c85eff9bc046a3b0da41755e12" +dependencies = [ + "as-raw-xcb-connection", + "gethostname", + "libc", + "libloading 0.8.0", + "once_cell", + "rustix", + "x11rb-protocol", +] + +[[package]] +name = "x11rb-protocol" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec107c4503ea0b4a98ef47356329af139c0a4f7750e621cf2973cd3385ebcb3d" + [[package]] name = "x25519-dalek" version = "2.0.1" @@ -5611,6 +6472,31 @@ dependencies = [ "time", ] +[[package]] +name = "xcursor" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ef33da6b1660b4ddbfb3aef0ade110c8b8a781a3b6382fa5f2b5b040fd55f61" + +[[package]] +name = "xkbcommon-dl" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" +dependencies = [ + "bitflags 2.6.0", + "dlib", + "log", + "once_cell", + "xkeysym", +] + +[[package]] +name = "xkeysym" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" + [[package]] name = "xml-rs" version = "0.8.21" diff --git a/Cargo.toml b/Cargo.toml index 5ff8a49ab..c0261eb4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,7 @@ resolver = "2" [features] default = ["web_renderer"] +update_snapshots = [] decklink = ["compositor_api/decklink"] web_renderer = ["dep:compositor_chromium", "compositor_api/web_renderer"] diff --git a/build_tools/nix/package.nix b/build_tools/nix/package.nix index 2c1d9e512..f28ce969f 100644 --- a/build_tools/nix/package.nix +++ b/build_tools/nix/package.nix @@ -51,7 +51,6 @@ rustPlatform.buildRustPackage { '' rm -f $out/bin/live_compositor rm -f $out/bin/package_for_release - rm -f $out/bin/update_snapshots mv $out/bin/main_process $out/bin/live_compositor '' + ( diff --git a/compositor_api/src/types/component.rs b/compositor_api/src/types/component.rs index b08762531..d8cac4430 100644 --- a/compositor_api/src/types/component.rs +++ b/compositor_api/src/types/component.rs @@ -36,14 +36,14 @@ pub struct View { /// List of component's children. pub children: Option>, - /// Width of a component in pixels. Exact behavior might be different based on the parent - /// component: + /// Width of a component in pixels (without a border). Exact behavior might be different + /// based on the parent component: /// - If the parent component is a layout, check sections "Absolute positioning" and "Static /// positioning" of that component. /// - If the parent component is not a layout, then this field is required. pub width: Option, - /// Height of a component in pixels. Exact behavior might be different based on the parent - /// component: + /// Height of a component in pixels (without a border). Exact behavior might be different + /// based on the parent component: /// - If the parent component is a layout, check sections "Absolute positioning" and "Static /// positioning" of that component. /// - If the parent component is not a layout, then this field is required. @@ -52,16 +52,16 @@ pub struct View { /// Direction defines how static children are positioned inside a View component. pub direction: Option, - /// Distance in pixels between this component's top edge and its parent's top edge. + /// Distance in pixels between this component's top edge and its parent's top edge (including a border). /// If this field is defined, then the component will ignore a layout defined by its parent. pub top: Option, - /// Distance in pixels between this component's left edge and its parent's left edge. + /// Distance in pixels between this component's left edge and its parent's left edge (including a border). /// If this field is defined, this element will be absolutely positioned, instead of being /// laid out by its parent. pub left: Option, - /// Distance in pixels between the bottom edge of this component and the bottom edge of its parent. - /// If this field is defined, this element will be absolutely positioned, instead of being - /// laid out by its parent. + /// Distance in pixels between the bottom edge of this component and the bottom edge of its + /// parent (including a border). If this field is defined, this element will be absolutely + /// positioned, instead of being laid out by its parent. pub bottom: Option, /// Distance in pixels between this component's right edge and its parent's right edge. /// If this field is defined, this element will be absolutely positioned, instead of being @@ -80,6 +80,27 @@ pub struct View { /// (**default=`"#00000000"`**) Background color in a `"#RRGGBBAA"` format. pub background_color_rgba: Option, + + /// (**default=`0.0`**) Radius of a rounded corner. + pub border_radius: Option, + + /// (**default=`0.0`**) Border width. + pub border_width: Option, + + /// (**default=`"#00000000"`**) Border color in a `"#RRGGBBAA"` format. + pub border_color_rgba: Option, + + /// List of box shadows. + pub box_shadow: Option>, +} + +#[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] +#[serde(deny_unknown_fields)] +pub struct BoxShadow { + pub offset_x: Option, + pub offset_y: Option, + pub color_rgba: Option, + pub blur_radius: Option, } #[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] @@ -126,29 +147,29 @@ pub struct Rescaler { /// (**default=`"center"`**) Vertical alignment. pub vertical_align: Option, - /// Width of a component in pixels. Exact behavior might be different based on the parent - /// component: + /// Width of a component in pixels (without a border). Exact behavior might be different + /// based on the parent component: /// - If the parent component is a layout, check sections "Absolute positioning" and "Static /// positioning" of that component. /// - If the parent component is not a layout, then this field is required. pub width: Option, - /// Height of a component in pixels. Exact behavior might be different based on the parent - /// component: + /// Height of a component in pixels (without a border). Exact behavior might be different + /// based on the parent component: /// - If the parent component is a layout, check sections "Absolute positioning" and "Static /// positioning" of that component. /// - If the parent component is not a layout, then this field is required. pub height: Option, - /// Distance in pixels between this component's top edge and its parent's top edge. + /// Distance in pixels between this component's top edge and its parent's top edge (including a border). /// If this field is defined, then the component will ignore a layout defined by its parent. pub top: Option, - /// Distance in pixels between this component's left edge and its parent's left edge. + /// Distance in pixels between this component's left edge and its parent's left edge (including a border). /// If this field is defined, this element will be absolutely positioned, instead of being /// laid out by its parent. pub left: Option, - /// Distance in pixels between this component's bottom edge and its parent's bottom edge. - /// If this field is defined, this element will be absolutely positioned, instead of being - /// laid out by its parent. + /// Distance in pixels between the bottom edge of this component and the bottom edge of its + /// parent (including a border). If this field is defined, this element will be absolutely + /// positioned, instead of being laid out by its parent. pub bottom: Option, /// Distance in pixels between this component's right edge and its parent's right edge. /// If this field is defined, this element will be absolutely positioned, instead of being @@ -161,6 +182,18 @@ pub struct Rescaler { /// Defines how this component will behave during a scene update. This will only have an /// effect if the previous scene already contained a `Rescaler` component with the same id. pub transition: Option, + + /// (**default=`0.0`**) Radius of a rounded corner. + pub border_radius: Option, + + /// (**default=`0.0`**) Border width. + pub border_width: Option, + + /// (**default=`"#00000000"`**) Border color in a `"#RRGGBBAA"` format. + pub border_color_rgba: Option, + + /// List of box shadows. + pub box_shadow: Option>, } #[derive(Debug, Serialize, Deserialize, Clone, JsonSchema)] @@ -183,7 +216,8 @@ pub struct WebView { /// List of component's children. pub children: Option>, - /// Id of a web renderer instance. It identifies an instance registered using a [`register web renderer`](../routes.md#register-web-renderer-instance) request. + /// Id of a web renderer instance. It identifies an instance registered using a + /// [`register web renderer`](../routes.md#register-web-renderer-instance) request. /// /// :::warning /// You can only refer to specific instances in one Component at a time. @@ -217,8 +251,10 @@ pub struct Shader { /// @group(1) @binding(0) var /// ``` /// :::note - /// This object's structure must match the structure defined in a shader source code. Currently, we do not handle memory layout automatically. - /// To achieve the correct memory alignment, you might need to pad your data with additional fields. See [WGSL documentation](https://www.w3.org/TR/WGSL/#alignment-and-size) for more details. + /// This object's structure must match the structure defined in a shader source code. + /// Currently, we do not handle memory layout automatically. To achieve the correct memory + /// alignment, you might need to pad your data with additional fields. See + /// [WGSL documentation](https://www.w3.org/TR/WGSL/#alignment-and-size) for more details. /// ::: pub shader_param: Option, /// Resolution of a texture where shader will be executed. @@ -378,4 +414,6 @@ pub struct Tiles { /// Defines how this component will behave during a scene update. This will only have an /// effect if the previous scene already contained a `Tiles` component with the same id. pub transition: Option, + + pub border_radius: Option, } diff --git a/compositor_api/src/types/from_component.rs b/compositor_api/src/types/from_component.rs index 66a4346ac..5bc2ad9fb 100644 --- a/compositor_api/src/types/from_component.rs +++ b/compositor_api/src/types/from_component.rs @@ -1,6 +1,7 @@ use std::sync::Arc; use compositor_render::scene; +use compositor_render::scene::BorderRadius; use compositor_render::scene::Position; use compositor_render::MAX_NODE_RESOLUTION; @@ -101,6 +102,18 @@ impl TryFrom for scene::ViewComponent { .map(TryInto::try_into) .unwrap_or(Ok(scene::RGBAColor(0, 0, 0, 0)))?, transition: view.transition.map(TryInto::try_into).transpose()?, + border_radius: BorderRadius::new_with_radius(view.border_radius.unwrap_or(0.0)), + border_width: view.border_width.unwrap_or(0.0), + border_color: view + .border_color_rgba + .map(TryInto::try_into) + .unwrap_or(Ok(scene::RGBAColor(0, 0, 0, 0)))?, + box_shadow: view + .box_shadow + .unwrap_or_default() + .into_iter() + .map(TryInto::try_into) + .collect::>()?, }) } } @@ -165,6 +178,18 @@ impl TryFrom for scene::RescalerComponent { .unwrap_or(VerticalAlign::Center) .into(), transition: rescaler.transition.map(TryInto::try_into).transpose()?, + border_radius: BorderRadius::new_with_radius(rescaler.border_radius.unwrap_or(0.0)), + border_width: rescaler.border_width.unwrap_or(0.0), + border_color: rescaler + .border_color_rgba + .map(TryInto::try_into) + .unwrap_or(Ok(scene::RGBAColor(0, 0, 0, 0)))?, + box_shadow: rescaler + .box_shadow + .unwrap_or_default() + .into_iter() + .map(TryInto::try_into) + .collect::>()?, }) } } @@ -339,3 +364,19 @@ impl TryFrom for scene::TilesComponent { Ok(result) } } + +impl TryFrom for scene::BoxShadow { + type Error = TypeError; + + fn try_from(value: BoxShadow) -> Result { + Ok(Self { + offset_x: value.offset_x.unwrap_or(0.0), + offset_y: value.offset_y.unwrap_or(0.0), + blur_radius: value.blur_radius.unwrap_or(0.0), + color: value + .color_rgba + .map(TryInto::try_into) + .unwrap_or(Ok(scene::RGBAColor(255, 255, 255, 255)))?, + }) + } +} diff --git a/compositor_pipeline/src/pipeline.rs b/compositor_pipeline/src/pipeline.rs index 00cfce8cf..fac91d36e 100644 --- a/compositor_pipeline/src/pipeline.rs +++ b/compositor_pipeline/src/pipeline.rs @@ -136,7 +136,7 @@ pub struct PipelineCtx { pub event_emitter: Arc, pub tokio_rt: Arc, #[cfg(feature = "vk-video")] - pub vulkan_ctx: Option>, + pub vulkan_ctx: Option, } impl std::fmt::Debug for PipelineCtx { @@ -159,6 +159,7 @@ impl Pipeline { opts.force_gpu, opts.wgpu_features, Default::default(), + None, )?), #[cfg(not(feature = "vk-video"))] None => None, @@ -385,6 +386,15 @@ impl Pipeline { .outputs .get(&output_id) .ok_or_else(|| UpdateSceneError::OutputNotRegistered(output_id.clone()))?; + + if let Some(cond) = &output.video_end_condition { + if cond.did_output_end() { + // Ignore updates after EOS + warn!("Received output update on a finished output"); + return Ok(()); + } + } + let (Some(resolution), Some(frame_format)) = ( output.output.resolution(), output.output.output_frame_format(), @@ -403,6 +413,19 @@ impl Pipeline { output_id: &OutputId, audio: AudioMixingParams, ) -> Result<(), UpdateSceneError> { + let output = self + .outputs + .get(output_id) + .ok_or_else(|| UpdateSceneError::OutputNotRegistered(output_id.clone()))?; + + if let Some(cond) = &output.audio_end_condition { + if cond.did_output_end() { + // Ignore updates after EOS + warn!("Received output update on a finished output"); + return Ok(()); + } + } + info!(?output_id, "Update audio mixer {:#?}", audio); self.audio_mixer.update_output(output_id, audio) } diff --git a/compositor_pipeline/src/pipeline/decoder/video/vulkan_video.rs b/compositor_pipeline/src/pipeline/decoder/video/vulkan_video.rs index 8e2363412..10340e777 100644 --- a/compositor_pipeline/src/pipeline/decoder/video/vulkan_video.rs +++ b/compositor_pipeline/src/pipeline/decoder/video/vulkan_video.rs @@ -1,9 +1,9 @@ -use std::sync::Arc; +use std::{sync::Arc, time::Duration}; use compositor_render::{Frame, FrameData, InputId, Resolution}; use crossbeam_channel::{Receiver, Sender}; use tracing::{debug, error, span, trace, warn, Level}; -use vk_video::{Decoder, VulkanCtx}; +use vk_video::VulkanDevice; use crate::{ error::InputInitError, @@ -17,7 +17,7 @@ pub fn start_vulkan_video_decoder_thread( frame_sender: Sender>, input_id: InputId, ) -> Result<(), InputInitError> { - let Some(vulkan_ctx) = pipeline_ctx.vulkan_ctx.as_ref().map(|ctx| ctx.clone()) else { + let Some(vulkan_ctx) = pipeline_ctx.vulkan_ctx.clone() else { return Err(InputInitError::VulkanContextRequiredForVulkanDecoder); }; @@ -33,7 +33,7 @@ pub fn start_vulkan_video_decoder_thread( ) .entered(); run_decoder_thread( - vulkan_ctx, + vulkan_ctx.device, init_result_sender, chunks_receiver, frame_sender, @@ -47,12 +47,12 @@ pub fn start_vulkan_video_decoder_thread( } fn run_decoder_thread( - vulkan_ctx: Arc, + vulkan_device: Arc, init_result_sender: Sender>, chunks_receiver: Receiver>, frame_sender: Sender>, ) { - let mut decoder = match Decoder::new(vulkan_ctx) { + let mut decoder = match vulkan_device.create_wgpu_textures_decoder() { Ok(decoder) => { init_result_sender.send(Ok(())).unwrap(); decoder @@ -79,7 +79,7 @@ fn run_decoder_thread( continue; } - let result = match decoder.decode_to_wgpu_textures(&chunk.data) { + let result = match decoder.decode(&chunk.data, Some(chunk.pts.as_micros() as u64)) { Ok(res) => res, Err(err) => { warn!("Failed to decode frame: {err}"); @@ -87,7 +87,7 @@ fn run_decoder_thread( } }; - for frame in result { + for vk_video::Frame { frame, pts } in result { let resolution = Resolution { width: frame.width() as usize, height: frame.height() as usize, @@ -95,7 +95,7 @@ fn run_decoder_thread( let frame = Frame { data: FrameData::Nv12WgpuTexture(frame.into()), - pts: chunk.pts, + pts: Duration::from_micros(pts.unwrap()), resolution, }; diff --git a/compositor_pipeline/src/pipeline/encoder/ffmpeg_h264.rs b/compositor_pipeline/src/pipeline/encoder/ffmpeg_h264.rs index c04b3a182..ad3eb22d1 100644 --- a/compositor_pipeline/src/pipeline/encoder/ffmpeg_h264.rs +++ b/compositor_pipeline/src/pipeline/encoder/ffmpeg_h264.rs @@ -4,6 +4,7 @@ use compositor_render::{Frame, FrameData, OutputId, Resolution}; use crossbeam_channel::{Receiver, Sender}; use ffmpeg_next::{ codec::{Context, Id}, + encoder::Video, format::Pixel, frame, Dictionary, Packet, Rational, }; @@ -239,46 +240,63 @@ fn run_encoder_thread( continue; } - loop { - match encoder.receive_packet(&mut packet) { - Ok(_) => { - match encoded_chunk_from_av_packet( - &packet, - EncodedChunkKind::Video(VideoCodec::H264), - 1_000_000, - ) { - Ok(chunk) => { - trace!(pts=?packet.pts(), "H264 encoder produced an encoded packet."); - if packet_sender.send(EncoderOutputEvent::Data(chunk)).is_err() { - warn!("Failed to send encoded video from H264 encoder. Channel closed."); - return Ok(()); - } - } - Err(e) => { - warn!("failed to parse an ffmpeg packet received from encoder: {e}",); - break; - } - } - } - - Err(ffmpeg_next::Error::Other { - errno: ffmpeg_next::error::EAGAIN, - }) => break, // encoder needs more frames to produce a packet - - Err(e) => { - error!("Encoder error: {e}."); - break; - } + while let Some(chunk) = receive_chunk(&mut encoder, &mut packet) { + if packet_sender.send(EncoderOutputEvent::Data(chunk)).is_err() { + warn!("Failed to send encoded video from H264 encoder. Channel closed."); + return Ok(()); } } } + // Flush the encoder + if let Err(e) = encoder.send_eof() { + error!("Failed to enter draining mode on encoder: {e}."); + } + while let Some(chunk) = receive_chunk(&mut encoder, &mut packet) { + if packet_sender.send(EncoderOutputEvent::Data(chunk)).is_err() { + warn!("Failed to send encoded video from H264 encoder. Channel closed."); + return Ok(()); + } + } + if let Err(_err) = packet_sender.send(EncoderOutputEvent::VideoEOS) { warn!("Failed to send EOS from H264 encoder. Channel closed.") } Ok(()) } +fn receive_chunk(encoder: &mut Video, packet: &mut Packet) -> Option { + match encoder.receive_packet(packet) { + Ok(_) => { + match encoded_chunk_from_av_packet( + packet, + EncodedChunkKind::Video(VideoCodec::H264), + 1_000_000, + ) { + Ok(chunk) => { + trace!(pts=?packet.pts(), "H264 encoder produced an encoded packet."); + Some(chunk) + } + Err(e) => { + warn!("failed to parse an ffmpeg packet received from encoder: {e}",); + None + } + } + } + + Err(ffmpeg_next::Error::Eof) => None, + + Err(ffmpeg_next::Error::Other { + errno: ffmpeg_next::error::EAGAIN, + }) => None, // encoder needs more frames to produce a packet + + Err(e) => { + error!("Encoder error: {e}."); + None + } + } +} + #[derive(Debug)] struct FrameConversionError(String); diff --git a/compositor_pipeline/src/pipeline/encoder/opus.rs b/compositor_pipeline/src/pipeline/encoder/opus.rs index 1e83b022a..97d333189 100644 --- a/compositor_pipeline/src/pipeline/encoder/opus.rs +++ b/compositor_pipeline/src/pipeline/encoder/opus.rs @@ -38,7 +38,7 @@ impl OpusEncoder { std::thread::Builder::new() .name("Opus encoder thread".to_string()) .spawn(move || { - let _span = span!(Level::INFO, "Opus encoder thread",).entered(); + let _span = span!(Level::INFO, "Opus encoder thread").entered(); run_encoder_thread(encoder, samples_batch_receiver, packets_sender) }) .unwrap(); diff --git a/compositor_pipeline/src/pipeline/graphics_context.rs b/compositor_pipeline/src/pipeline/graphics_context.rs index d0bc15d0c..ea30eb26f 100644 --- a/compositor_pipeline/src/pipeline/graphics_context.rs +++ b/compositor_pipeline/src/pipeline/graphics_context.rs @@ -1,14 +1,23 @@ use crate::error::InitPipelineError; -use compositor_render::{create_wgpu_ctx, error::InitRendererEngineError}; +use compositor_render::{create_wgpu_ctx, error::InitRendererEngineError, WgpuComponents}; use std::sync::Arc; +#[cfg(feature = "vk-video")] +#[derive(Debug, Clone)] +pub struct VulkanCtx { + pub device: Arc, + pub instance: Arc, +} + #[derive(Debug)] pub struct GraphicsContext { pub device: Arc, pub queue: Arc, + pub adapter: Arc, + pub instance: Arc, #[cfg(feature = "vk-video")] - pub vulkan_ctx: Option>, + pub vulkan_ctx: Option, } impl GraphicsContext { @@ -17,6 +26,7 @@ impl GraphicsContext { force_gpu: bool, features: wgpu::Features, limits: wgpu::Limits, + mut compatible_surface: Option<&mut wgpu::Surface<'_>>, ) -> Result { use compositor_render::{required_wgpu_features, set_required_wgpu_limits}; use tracing::warn; @@ -26,22 +36,36 @@ impl GraphicsContext { let limits = set_required_wgpu_limits(limits); - match vk_video::VulkanCtx::new(vulkan_features, limits.clone()) { - Ok(ctx) => Ok(GraphicsContext { - device: ctx.wgpu_ctx.device.clone(), - queue: ctx.wgpu_ctx.queue.clone(), - vulkan_ctx: Some(ctx.into()), + match vk_video::VulkanInstance::new().and_then(|instance| { + let device = + instance.create_device(vulkan_features, limits.clone(), &mut compatible_surface)?; + + Ok((instance, device)) + }) { + Ok((instance, device)) => Ok(GraphicsContext { + device: device.wgpu_device.clone(), + queue: device.wgpu_queue.clone(), + adapter: device.wgpu_adapter.clone(), + instance: instance.wgpu_instance.clone(), + vulkan_ctx: Some(VulkanCtx { instance, device }), }), Err(err) => { warn!("Cannot initialize vulkan video decoding context. Reason: {err}. Initializing without vulkan video support."); - let (device, queue) = create_wgpu_ctx(force_gpu, features, limits) + let WgpuComponents { + instance, + adapter, + device, + queue, + } = create_wgpu_ctx(force_gpu, features, limits, compatible_surface.as_deref()) .map_err(InitRendererEngineError::FailedToInitWgpuCtx)?; Ok(GraphicsContext { device, queue, + adapter, + instance, vulkan_ctx: None, }) } @@ -53,10 +77,21 @@ impl GraphicsContext { force_gpu: bool, features: wgpu::Features, limits: wgpu::Limits, + compatible_surface: Option<&mut wgpu::Surface<'_>>, ) -> Result { - let (device, queue) = create_wgpu_ctx(force_gpu, features, limits) + let WgpuComponents { + instance, + adapter, + device, + queue, + } = create_wgpu_ctx(force_gpu, features, limits, compatible_surface.as_deref()) .map_err(InitRendererEngineError::FailedToInitWgpuCtx)?; - Ok(GraphicsContext { device, queue }) + Ok(GraphicsContext { + device, + queue, + adapter, + instance, + }) } } diff --git a/compositor_pipeline/src/pipeline/pipeline_output.rs b/compositor_pipeline/src/pipeline/pipeline_output.rs index e4c7bf08f..5915cc1e3 100644 --- a/compositor_pipeline/src/pipeline/pipeline_output.rs +++ b/compositor_pipeline/src/pipeline/pipeline_output.rs @@ -234,6 +234,10 @@ impl PipelineOutputEndConditionState { EosStatus::None } + pub(super) fn did_output_end(&self) -> bool { + self.did_end + } + pub(super) fn on_input_registered(&mut self, input_id: &InputId) { self.on_event(StateChange::AddInput(input_id)) } diff --git a/compositor_pipeline/src/queue/queue_thread.rs b/compositor_pipeline/src/queue/queue_thread.rs index 4bd47ff63..b9f3c9dc4 100644 --- a/compositor_pipeline/src/queue/queue_thread.rs +++ b/compositor_pipeline/src/queue/queue_thread.rs @@ -236,7 +236,9 @@ impl VideoQueueProcessor { let pts = frames_batch.pts; debug!(?pts, "Pushing video frames."); if is_required { - self.sender.send(frames_batch).unwrap() + if self.sender.send(frames_batch).is_err() { + warn!(?pts, "Dropping video frame on queue output."); + } } else { let send_deadline = self.queue_start_time.add(frames_batch.pts); if self @@ -341,7 +343,9 @@ impl AudioQueueProcessor { let pts_range = (samples.start_pts, samples.end_pts); debug!(?pts_range, "Pushing audio samples."); if is_required { - self.sender.send(samples).unwrap() + if self.sender.send(samples).is_err() { + warn!(?pts_range, "Dropping audio batch on queue output."); + } } else if self.sender.try_send(samples).is_err() { warn!(?pts_range, "Dropping audio batch on queue output.") } diff --git a/compositor_render/fonts/Inter_18pt-Bold.ttf b/compositor_render/fonts/Inter_18pt-Bold.ttf new file mode 100644 index 000000000..cd13f60ce Binary files /dev/null and b/compositor_render/fonts/Inter_18pt-Bold.ttf differ diff --git a/compositor_render/src/lib.rs b/compositor_render/src/lib.rs index 5d598473f..3e3a4e3ea 100644 --- a/compositor_render/src/lib.rs +++ b/compositor_render/src/lib.rs @@ -20,7 +20,7 @@ pub use state::RendererOptions; pub use state::RendererSpec; pub use wgpu::WgpuFeatures; -pub use wgpu::{create_wgpu_ctx, required_wgpu_features, set_required_wgpu_limits}; +pub use wgpu::{create_wgpu_ctx, required_wgpu_features, set_required_wgpu_limits, WgpuComponents}; pub mod image { pub use crate::transformations::image_renderer::{ImageSource, ImageSpec, ImageType}; diff --git a/compositor_render/src/scene/components.rs b/compositor_render/src/scene/components.rs index e0396c054..1ad769a45 100644 --- a/compositor_render/src/scene/components.rs +++ b/compositor_render/src/scene/components.rs @@ -3,10 +3,12 @@ use std::{fmt::Display, sync::Arc, time::Duration}; use crate::{InputId, RendererId}; use super::{ - AbsolutePosition, Component, HorizontalAlign, InterpolationKind, RGBAColor, Size, VerticalAlign, + AbsolutePosition, BorderRadius, BoxShadow, Component, HorizontalAlign, InterpolationKind, + RGBAColor, Size, VerticalAlign, }; mod interpolation; +mod position; #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct ComponentId(pub Arc); @@ -140,6 +142,12 @@ pub struct ViewComponent { pub overflow: Overflow, pub background_color: RGBAColor, + + pub border_radius: BorderRadius, + pub border_width: f32, + pub border_color: RGBAColor, + + pub box_shadow: Vec, } #[derive(Debug, Clone, Copy)] @@ -181,6 +189,12 @@ pub struct RescalerComponent { pub mode: RescaleMode, pub horizontal_align: HorizontalAlign, pub vertical_align: VerticalAlign, + + pub border_radius: BorderRadius, + pub border_width: f32, + pub border_color: RGBAColor, + + pub box_shadow: Vec, } #[derive(Debug, Clone, Copy)] diff --git a/compositor_render/src/scene/components/interpolation.rs b/compositor_render/src/scene/components/interpolation.rs index d2872457b..a01e95c6e 100644 --- a/compositor_render/src/scene/components/interpolation.rs +++ b/compositor_render/src/scene/components/interpolation.rs @@ -1,4 +1,7 @@ -use crate::scene::types::interpolation::{ContinuousValue, InterpolationState}; +use crate::scene::{ + types::interpolation::{ContinuousValue, InterpolationState}, + BorderRadius, BoxShadow, +}; use super::{AbsolutePosition, Position}; @@ -46,3 +49,42 @@ impl ContinuousValue for AbsolutePosition { } } } + +impl ContinuousValue for BorderRadius { + fn interpolate(start: &Self, end: &Self, state: InterpolationState) -> Self { + Self { + top_left: ContinuousValue::interpolate(&start.top_left, &end.top_left, state), + top_right: ContinuousValue::interpolate(&start.top_right, &end.top_right, state), + bottom_right: ContinuousValue::interpolate( + &start.bottom_right, + &end.bottom_right, + state, + ), + bottom_left: ContinuousValue::interpolate(&start.bottom_left, &end.bottom_left, state), + } + } +} + +impl ContinuousValue for Vec { + fn interpolate(start: &Self, end: &Self, state: InterpolationState) -> Self { + start + .iter() + .zip(end.iter()) + // interpolate as long both lists have entries + .map(|(start, end)| ContinuousValue::interpolate(start, end, state)) + // add remaining elements if end is longer + .chain(end.iter().skip(usize::min(start.len(), end.len())).copied()) + .collect() + } +} + +impl ContinuousValue for BoxShadow { + fn interpolate(start: &Self, end: &Self, state: InterpolationState) -> Self { + Self { + offset_x: ContinuousValue::interpolate(&start.offset_x, &end.offset_x, state), + offset_y: ContinuousValue::interpolate(&start.offset_y, &end.offset_y, state), + blur_radius: ContinuousValue::interpolate(&start.blur_radius, &end.blur_radius, state), + color: end.color, + } + } +} diff --git a/compositor_render/src/scene/components/position.rs b/compositor_render/src/scene/components/position.rs new file mode 100644 index 000000000..0525293d2 --- /dev/null +++ b/compositor_render/src/scene/components/position.rs @@ -0,0 +1,27 @@ +use crate::scene::AbsolutePosition; + +use super::Position; + +impl Position { + pub(crate) fn with_border(self, border_width: f32) -> Self { + match self { + Position::Static { width, height } => Self::Static { + width: width.map(|w| w + 2.0 * border_width), + height: height.map(|h| h + 2.0 * border_width), + }, + Position::Absolute(AbsolutePosition { + width, + height, + position_horizontal, + position_vertical, + rotation_degrees, + }) => Self::Absolute(AbsolutePosition { + width: width.map(|w| w + 2.0 * border_width), + height: height.map(|h| h + 2.0 * border_width), + position_horizontal, + position_vertical, + rotation_degrees, + }), + } + } +} diff --git a/compositor_render/src/scene/layout.rs b/compositor_render/src/scene/layout.rs index 8a2ab7d09..710661c46 100644 --- a/compositor_render/src/scene/layout.rs +++ b/compositor_render/src/scene/layout.rs @@ -7,8 +7,8 @@ use crate::{ use super::{ rescaler_component::StatefulRescalerComponent, tiles_component::StatefulTilesComponent, - view_component::StatefulViewComponent, AbsolutePosition, ComponentId, HorizontalPosition, - Position, Size, StatefulComponent, VerticalPosition, + view_component::StatefulViewComponent, AbsolutePosition, BorderRadius, ComponentId, + HorizontalPosition, Position, RGBAColor, Size, StatefulComponent, VerticalPosition, }; #[derive(Debug, Clone)] @@ -49,6 +49,7 @@ impl StatefulLayoutComponent { } } + // External position of a component (includes border, padding, ...) pub(super) fn position(&self, pts: Duration) -> Position { match self { StatefulLayoutComponent::View(view) => view.position(pts), @@ -177,6 +178,7 @@ impl StatefulLayoutComponent { let rotation_degrees = position.rotation_degrees; let content = Self::layout_content(child, 0); let crop = None; + let mask = None; match child { StatefulComponent::Layout(layout_component) => { @@ -194,10 +196,15 @@ impl StatefulLayoutComponent { scale_x: 1.0, scale_y: 1.0, crop, + mask, content, child_nodes_count, children: vec![children_layouts], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } _non_layout_components => { @@ -215,10 +222,15 @@ impl StatefulLayoutComponent { scale_x: 1.0, scale_y: 1.0, crop, + mask, content, child_nodes_count, children: vec![], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } } diff --git a/compositor_render/src/scene/rescaler_component.rs b/compositor_render/src/scene/rescaler_component.rs index 259dcf60e..4bd40d8d5 100644 --- a/compositor_render/src/scene/rescaler_component.rs +++ b/compositor_render/src/scene/rescaler_component.rs @@ -8,8 +8,8 @@ use super::{ scene_state::BuildStateTreeCtx, transition::{TransitionOptions, TransitionState}, types::interpolation::ContinuousValue, - Component, ComponentId, HorizontalAlign, IntermediateNode, Position, RescaleMode, SceneError, - Size, StatefulComponent, VerticalAlign, + BorderRadius, BoxShadow, Component, ComponentId, HorizontalAlign, IntermediateNode, Position, + RGBAColor, RescaleMode, SceneError, Size, StatefulComponent, VerticalAlign, }; mod interpolation; @@ -31,6 +31,12 @@ struct RescalerComponentParam { mode: RescaleMode, horizontal_align: HorizontalAlign, vertical_align: VerticalAlign, + + border_radius: BorderRadius, + border_width: f32, + border_color: RGBAColor, + + box_shadow: Vec, } impl StatefulRescalerComponent { @@ -52,7 +58,8 @@ impl StatefulRescalerComponent { } pub(super) fn position(&self, pts: Duration) -> Position { - self.transition_snapshot(pts).position + let rescaler = self.transition_snapshot(pts); + rescaler.position.with_border(rescaler.border_width) } pub(super) fn component_id(&self) -> Option<&ComponentId> { @@ -107,7 +114,7 @@ impl RescalerComponent { previous_state.and_then(|s| s.transition.clone()), ctx.last_render_pts, ); - let view = StatefulRescalerComponent { + let rescaler = StatefulRescalerComponent { start, end: RescalerComponentParam { id: self.id, @@ -115,12 +122,16 @@ impl RescalerComponent { mode: self.mode, horizontal_align: self.horizontal_align, vertical_align: self.vertical_align, + border_radius: self.border_radius, + border_width: self.border_width, + border_color: self.border_color, + box_shadow: self.box_shadow, }, transition, child: Box::new(Component::stateful_component(*self.child, ctx)?), }; Ok(StatefulComponent::Layout( - StatefulLayoutComponent::Rescaler(view), + StatefulLayoutComponent::Rescaler(rescaler), )) } } diff --git a/compositor_render/src/scene/rescaler_component/interpolation.rs b/compositor_render/src/scene/rescaler_component/interpolation.rs index 019100c9b..78dc02482 100644 --- a/compositor_render/src/scene/rescaler_component/interpolation.rs +++ b/compositor_render/src/scene/rescaler_component/interpolation.rs @@ -10,6 +10,18 @@ impl ContinuousValue for RescalerComponentParam { mode: end.mode, horizontal_align: end.horizontal_align, vertical_align: end.vertical_align, + border_radius: ContinuousValue::interpolate( + &start.border_radius, + &end.border_radius, + state, + ), + border_width: ContinuousValue::interpolate( + &start.border_width, + &end.border_width, + state, + ), + border_color: end.border_color, + box_shadow: ContinuousValue::interpolate(&start.box_shadow, &end.box_shadow, state), } } } diff --git a/compositor_render/src/scene/rescaler_component/layout.rs b/compositor_render/src/scene/rescaler_component/layout.rs index cdf71b5db..7127ff103 100644 --- a/compositor_render/src/scene/rescaler_component/layout.rs +++ b/compositor_render/src/scene/rescaler_component/layout.rs @@ -2,10 +2,10 @@ use std::time::Duration; use crate::{ scene::{ - layout::StatefulLayoutComponent, HorizontalAlign, RescaleMode, Size, StatefulComponent, - VerticalAlign, + layout::StatefulLayoutComponent, BorderRadius, HorizontalAlign, RGBAColor, RescaleMode, + Size, StatefulComponent, VerticalAlign, }, - transformations::layout::{Crop, LayoutContent, NestedLayout}, + transformations::layout::{LayoutContent, Mask, NestedLayout}, }; use super::RescalerComponentParam; @@ -17,50 +17,58 @@ impl RescalerComponentParam { child: &mut StatefulComponent, pts: Duration, ) -> NestedLayout { + let content_size = Size { + width: f32::max(size.width - (2.0 * self.border_width), 0.0), + height: f32::max(size.height - (2.0 * self.border_width), 0.0), + }; let child_width = child.width(pts); let child_height = child.height(pts); match (child_width, child_height) { - (None, None) => self.layout_with_scale(size, child, pts, 1.0), + (None, None) => self.layout_with_scale(content_size, child, pts, 1.0), (None, Some(child_height)) => { - self.layout_with_scale(size, child, pts, size.height / child_height) + self.layout_with_scale(content_size, child, pts, content_size.height / child_height) } (Some(child_width), None) => { - self.layout_with_scale(size, child, pts, size.width / child_width) + self.layout_with_scale(content_size, child, pts, content_size.width / child_width) } (Some(child_width), Some(child_height)) => { let scale = match self.mode { - RescaleMode::Fit => { - f32::min(size.width / child_width, size.height / child_height) - } - RescaleMode::Fill => { - f32::max(size.width / child_width, size.height / child_height) - } + RescaleMode::Fit => f32::min( + content_size.width / child_width, + content_size.height / child_height, + ), + RescaleMode::Fill => f32::max( + content_size.width / child_width, + content_size.height / child_height, + ), }; - self.layout_with_scale(size, child, pts, scale) + self.layout_with_scale(content_size, child, pts, scale) } } } fn layout_with_scale( &self, - size: Size, + max_size: Size, // without borders child: &mut StatefulComponent, pts: Duration, scale: f32, ) -> NestedLayout { + let child_width = child.width(pts); + let child_height = child.height(pts); let (content, children, child_nodes_count) = match child { StatefulComponent::Layout(layout_component) => { - let children_layouts = layout_component.layout( + let children_layout = layout_component.layout( Size { - width: size.width / scale, - height: size.height / scale, + width: child_width.unwrap_or(max_size.width / scale), + height: child_height.unwrap_or(max_size.height / scale), }, pts, ); - let child_nodes_count = children_layouts.child_nodes_count; + let child_nodes_count = children_layout.child_nodes_count; ( LayoutContent::None, - vec![children_layouts], + vec![children_layout], child_nodes_count, ) } @@ -71,63 +79,74 @@ impl RescalerComponentParam { VerticalAlign::Top => 0.0, VerticalAlign::Bottom => child .height(pts) - .map(|height| size.height - (height * scale)) + .map(|height| max_size.height - (height * scale)) .unwrap_or(0.0), VerticalAlign::Center | VerticalAlign::Justified => child .height(pts) - .map(|height| (size.height - (height * scale)) / 2.0) + .map(|height| (max_size.height - (height * scale)) / 2.0) .unwrap_or(0.0), }; let left = match self.horizontal_align { HorizontalAlign::Left => 0.0, HorizontalAlign::Right => child .width(pts) - .map(|width| (size.width - (width * scale))) + .map(|width| (max_size.width - (width * scale))) .unwrap_or(0.0), HorizontalAlign::Center | HorizontalAlign::Justified => child .width(pts) - .map(|width| (size.width - (width * scale)) / (2.0)) + .map(|width| (max_size.width - (width * scale)) / (2.0)) .unwrap_or(0.0), }; let width = child .width(pts) .map(|child_width| child_width * scale) - .unwrap_or(size.width); + .unwrap_or(max_size.width); let height = child .height(pts) .map(|child_height| child_height * scale) - .unwrap_or(size.height); + .unwrap_or(max_size.height); NestedLayout { top: 0.0, left: 0.0, - width: size.width, - height: size.height, + width: max_size.width + (self.border_width * 2.0), + height: max_size.height + (self.border_width * 2.0), rotation_degrees: 0.0, scale_x: 1.0, scale_y: 1.0, - crop: Some(Crop { - top: 0.0, - left: 0.0, - width: size.width, - height: size.height, + crop: None, + mask: Some(Mask { + radius: self.border_radius - self.border_width, + top: self.border_width, + left: self.border_width, + width: max_size.width, + height: max_size.height, }), content: LayoutContent::None, children: vec![NestedLayout { - top, - left, + top: top + self.border_width, + left: left + self.border_width, width, height, rotation_degrees: 0.0, scale_x: scale, scale_y: scale, crop: None, + mask: None, content, child_nodes_count, children, + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], }], child_nodes_count, + border_width: self.border_width, + border_color: self.border_color, + border_radius: self.border_radius, + box_shadow: self.box_shadow.clone(), } } } diff --git a/compositor_render/src/scene/tiles_component/layout.rs b/compositor_render/src/scene/tiles_component/layout.rs index d7080be78..adc76c173 100644 --- a/compositor_render/src/scene/tiles_component/layout.rs +++ b/compositor_render/src/scene/tiles_component/layout.rs @@ -1,7 +1,7 @@ use std::time::Duration; use crate::{ - scene::{layout::StatefulLayoutComponent, RGBAColor, Size, StatefulComponent}, + scene::{layout::StatefulLayoutComponent, BorderRadius, RGBAColor, Size, StatefulComponent}, transformations::layout::{LayoutContent, NestedLayout}, }; @@ -29,9 +29,14 @@ pub(super) fn layout_tiles( scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: LayoutContent::Color(background_color), child_nodes_count: children.iter().map(|l| l.child_nodes_count).sum(), children, + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } @@ -64,9 +69,14 @@ fn layout_child(child: &mut StatefulComponent, tile: Option, pts: Duration scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: LayoutContent::None, child_nodes_count: children_layouts.child_nodes_count, children: vec![children_layouts], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } _ => { @@ -81,9 +91,14 @@ fn layout_child(child: &mut StatefulComponent, tile: Option, pts: Duration scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: StatefulLayoutComponent::layout_content(child, 0), child_nodes_count: 1, children: vec![], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } } diff --git a/compositor_render/src/scene/types.rs b/compositor_render/src/scene/types.rs index 66ff62f83..e0f243a9f 100644 --- a/compositor_render/src/scene/types.rs +++ b/compositor_render/src/scene/types.rs @@ -1,3 +1,5 @@ +use std::ops::{Add, Div, Mul, Sub}; + mod convert; pub(crate) mod interpolation; @@ -74,3 +76,79 @@ pub enum InterpolationKind { Bounce, CubicBezier { x1: f64, y1: f64, x2: f64, y2: f64 }, } + +#[derive(Debug, Clone, Copy)] +pub struct BorderRadius { + pub top_left: f32, + pub top_right: f32, + pub bottom_right: f32, + pub bottom_left: f32, +} + +impl BorderRadius { + pub const ZERO: BorderRadius = BorderRadius { + top_left: 0.0, + top_right: 0.0, + bottom_right: 0.0, + bottom_left: 0.0, + }; + + pub fn new_with_radius(radius: f32) -> Self { + Self { + top_left: radius, + top_right: radius, + bottom_right: radius, + bottom_left: radius, + } + } +} + +impl Mul for BorderRadius { + type Output = BorderRadius; + + fn mul(self, rhs: f32) -> Self::Output { + Self { + top_left: self.top_left * rhs, + top_right: self.top_right * rhs, + bottom_right: self.bottom_right * rhs, + bottom_left: self.bottom_left * rhs, + } + } +} + +impl Div for BorderRadius { + type Output = BorderRadius; + + fn div(self, rhs: f32) -> Self::Output { + self * (1.0 / rhs) + } +} + +impl Add for BorderRadius { + type Output = BorderRadius; + + fn add(self, rhs: f32) -> Self::Output { + Self { + top_left: f32::max(self.top_left + rhs, 0.0), + top_right: f32::max(self.top_right + rhs, 0.0), + bottom_right: f32::max(self.bottom_right + rhs, 0.0), + bottom_left: f32::max(self.bottom_left + rhs, 0.0), + } + } +} + +impl Sub for BorderRadius { + type Output = BorderRadius; + + fn sub(self, rhs: f32) -> Self::Output { + self + (-rhs) + } +} + +#[derive(Debug, Clone, Copy)] +pub struct BoxShadow { + pub offset_x: f32, + pub offset_y: f32, + pub blur_radius: f32, + pub color: RGBAColor, +} diff --git a/compositor_render/src/scene/view_component.rs b/compositor_render/src/scene/view_component.rs index 885cdd42e..ab133031b 100644 --- a/compositor_render/src/scene/view_component.rs +++ b/compositor_render/src/scene/view_component.rs @@ -8,8 +8,8 @@ use super::{ scene_state::BuildStateTreeCtx, transition::{TransitionOptions, TransitionState}, types::interpolation::ContinuousValue, - Component, ComponentId, IntermediateNode, Overflow, Position, RGBAColor, SceneError, Size, - StatefulComponent, + BorderRadius, BoxShadow, Component, ComponentId, IntermediateNode, Overflow, Position, + RGBAColor, SceneError, Size, StatefulComponent, }; mod interpolation; @@ -32,6 +32,11 @@ struct ViewComponentParam { overflow: Overflow, background_color: RGBAColor, + border_radius: BorderRadius, + border_width: f32, + border_color: RGBAColor, + + box_shadow: Vec, } impl StatefulViewComponent { @@ -51,8 +56,10 @@ impl StatefulViewComponent { self.children.iter_mut().collect() } + /// External position of a component (includes border) pub(super) fn position(&self, pts: Duration) -> Position { - self.view(pts).position + let view = self.view(pts); + view.position.with_border(view.border_width) } pub(super) fn component_id(&self) -> Option<&ComponentId> { @@ -119,6 +126,10 @@ impl ViewComponent { position: self.position, background_color: self.background_color, overflow: self.overflow, + border_radius: self.border_radius, + border_width: self.border_width, + border_color: self.border_color, + box_shadow: self.box_shadow, }, transition, children: self diff --git a/compositor_render/src/scene/view_component/interpolation.rs b/compositor_render/src/scene/view_component/interpolation.rs index b1fb958f6..e5afa293f 100644 --- a/compositor_render/src/scene/view_component/interpolation.rs +++ b/compositor_render/src/scene/view_component/interpolation.rs @@ -10,6 +10,18 @@ impl ContinuousValue for ViewComponentParam { position: ContinuousValue::interpolate(&start.position, &end.position, state), background_color: end.background_color, overflow: end.overflow, + border_radius: ContinuousValue::interpolate( + &start.border_radius, + &end.border_radius, + state, + ), + border_width: ContinuousValue::interpolate( + &start.border_width, + &end.border_width, + state, + ), + border_color: end.border_color, + box_shadow: ContinuousValue::interpolate(&start.box_shadow, &end.box_shadow, state), } } } diff --git a/compositor_render/src/scene/view_component/layout.rs b/compositor_render/src/scene/view_component/layout.rs index 2ace2fbaa..8b356f1a3 100644 --- a/compositor_render/src/scene/view_component/layout.rs +++ b/compositor_render/src/scene/view_component/layout.rs @@ -2,10 +2,10 @@ use std::time::Duration; use crate::{ scene::{ - layout::StatefulLayoutComponent, Overflow, Position, Size, StatefulComponent, - ViewChildrenDirection, + layout::StatefulLayoutComponent, BorderRadius, Overflow, Position, RGBAColor, Size, + StatefulComponent, ViewChildrenDirection, }, - transformations::layout::{Crop, LayoutContent, NestedLayout}, + transformations::layout::{LayoutContent, Mask, NestedLayout}, }; use super::ViewComponentParam; @@ -22,36 +22,52 @@ struct StaticChildLayoutOpts { /// For direction=column defines height of a static component static_child_size: f32, parent_size: Size, + /// border width before rescaling, it is used to calculate top/left offset correctly + /// when `overflow: fit` is set + parent_border_width: f32, } impl ViewComponentParam { pub(super) fn layout( &self, - size: Size, + size: Size, // how much size component has available(includes space for border) children: &mut [StatefulComponent], pts: Duration, ) -> NestedLayout { - let static_child_size = self.static_child_size(size, children, pts); - let (scale, crop) = match self.overflow { - Overflow::Visible => (1.0, None), + let content_size = Size { + width: f32::max(size.width - 2.0 * self.border_width, 0.0), + height: f32::max(size.height - 2.0 * self.border_width, 0.0), + }; + let static_child_size = self.static_child_size(content_size, children, pts); + let (scale, crop, mask) = match self.overflow { + Overflow::Visible => (1.0, None, None), Overflow::Hidden => ( 1.0, - Some(Crop { - top: 0.0, - left: 0.0, - width: size.width, - height: size.height, + None, + Some(Mask { + radius: self.border_radius - self.border_width, + top: self.border_width, + left: self.border_width, + width: content_size.width, + height: content_size.height, }), ), Overflow::Fit => ( - self.scale_factor_for_overflow_fit(size, children, pts), + self.scale_factor_for_overflow_fit(content_size, children, pts), None, + Some(Mask { + radius: self.border_radius - self.border_width, + top: self.border_width, + left: self.border_width, + width: content_size.width, + height: content_size.height, + }), ), }; // offset along x or y direction (depends on self.direction) where next // child component should be placed - let mut static_offset = 0.0; + let mut static_offset = self.border_width / scale; let children: Vec<_> = children .iter_mut() @@ -72,7 +88,8 @@ impl ViewComponentParam { height, static_offset, static_child_size, - parent_size: size, + parent_size: content_size, + parent_border_width: self.border_width / scale, }, pts, ); @@ -97,9 +114,14 @@ impl ViewComponentParam { scale_x: scale, scale_y: scale, crop, + mask, content: LayoutContent::Color(self.background_color), child_nodes_count: children.iter().map(|l| l.child_nodes_count).sum(), children, + border_width: self.border_width, + border_color: self.border_color, + border_radius: self.border_radius, + box_shadow: self.box_shadow.clone(), } } @@ -114,18 +136,18 @@ impl ViewComponentParam { ViewChildrenDirection::Row => { let width = opts.width.unwrap_or(opts.static_child_size); let height = opts.height.unwrap_or(opts.parent_size.height); - let top = 0.0; + let top = opts.parent_border_width; let left = static_offset; static_offset += width; - (top as f32, left, width, height) + (top, left, width, height) } ViewChildrenDirection::Column => { let height = opts.height.unwrap_or(opts.static_child_size); let width = opts.width.unwrap_or(opts.parent_size.width); let top = static_offset; - let left = 0.0; + let left = opts.parent_border_width; static_offset += height; - (top, left as f32, width, height) + (top, left, width, height) } }; let layout = match child { @@ -140,9 +162,14 @@ impl ViewComponentParam { scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: LayoutContent::None, child_nodes_count: children_layouts.child_nodes_count, children: vec![children_layouts], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } _ => NestedLayout { @@ -154,9 +181,14 @@ impl ViewComponentParam { scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: StatefulLayoutComponent::layout_content(child, 0), child_nodes_count: 1, children: vec![], + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], }, }; (layout, static_offset) @@ -165,6 +197,8 @@ impl ViewComponentParam { /// Calculate a size of a static child component that does not have it explicitly defined. /// Returned value represents width if the direction is `ViewChildrenDirection::Row` or /// height if the direction is `ViewChildrenDirection::Column`. + /// + /// size represents dimensions of content (without a border). fn static_child_size(&self, size: Size, children: &[StatefulComponent], pts: Duration) -> f32 { let max_size = match self.direction { super::ViewChildrenDirection::Row => size.width, @@ -190,7 +224,7 @@ impl ViewComponentParam { fn scale_factor_for_overflow_fit( &self, - size: Size, + content_size: Size, children: &[StatefulComponent], pts: Duration, ) -> f32 { @@ -198,8 +232,8 @@ impl ViewComponentParam { .sum_static_children_sizes(children, pts) .max(0.000000001); // avoid division by 0 let (max_size, max_alternative_size) = match self.direction { - super::ViewChildrenDirection::Row => (size.width, size.height), - super::ViewChildrenDirection::Column => (size.height, size.width), + super::ViewChildrenDirection::Row => (content_size.width, content_size.height), + super::ViewChildrenDirection::Column => (content_size.height, content_size.width), }; let max_alternative_size_for_child = Self::static_children_iter(children, pts) .map(|child| match self.direction { diff --git a/compositor_render/src/transformations/layout.rs b/compositor_render/src/transformations/layout.rs index 3a5ff2828..d09904b41 100644 --- a/compositor_render/src/transformations/layout.rs +++ b/compositor_render/src/transformations/layout.rs @@ -1,7 +1,7 @@ use std::{sync::Arc, time::Duration}; use crate::{ - scene::{RGBAColor, Size}, + scene::{BorderRadius, BoxShadow, RGBAColor, Size}, state::RenderCtx, wgpu::texture::NodeTexture, Resolution, @@ -11,16 +11,12 @@ mod flatten; mod layout_renderer; mod params; mod shader; -mod transformation_matrices; -use self::{ - params::{LayoutNodeParams, ParamsBuffer}, - shader::LayoutShader, -}; +use self::shader::LayoutShader; pub(crate) use layout_renderer::LayoutRenderer; + use log::error; -pub(crate) use transformation_matrices::{vertices_transformation_matrix, Position}; pub(crate) trait LayoutProvider: Send { fn layouts(&mut self, pts: Duration, inputs: &[Option]) -> NestedLayout; @@ -30,9 +26,10 @@ pub(crate) trait LayoutProvider: Send { pub(crate) struct LayoutNode { layout_provider: Box, shader: Arc, - params: ParamsBuffer, } +/// When rendering we cut this fragment from texture and stretch it on +/// the expected position #[derive(Debug, Clone)] pub struct Crop { pub top: f32, @@ -41,20 +38,55 @@ pub struct Crop { pub height: f32, } +#[derive(Debug, Clone)] +pub struct Mask { + pub radius: BorderRadius, + // position of parent on the output frame + pub top: f32, + pub left: f32, + pub width: f32, + pub height: f32, +} + #[derive(Debug, Clone)] struct RenderLayout { + // top-left corner, includes border top: f32, left: f32, + + // size on the output texture, includes border width: f32, height: f32, + + // Defines what should be cut from the content. + // - for texture defines part of the texture that will be stretched to + // the `self.width/self.height`. It might cut off border radius. + // - for box shadow + + // Rotated around the center rotation_degrees: f32, + // border radius needs to applied before cropping, so we can't just make it a part of a parent + // mask + border_radius: BorderRadius, + masks: Vec, content: RenderLayoutContent, } #[derive(Debug, Clone)] enum RenderLayoutContent { - Color(RGBAColor), - ChildNode { index: usize, crop: Crop }, + Color { + color: RGBAColor, + border_color: RGBAColor, + border_width: f32, + }, + ChildNode { + index: usize, + border_color: RGBAColor, + border_width: f32, + crop: Crop, + }, + #[allow(dead_code)] + BoxShadow { color: RGBAColor, blur_radius: f32 }, } #[derive(Debug, Clone)] @@ -66,19 +98,44 @@ pub enum LayoutContent { #[derive(Debug, Clone)] pub struct NestedLayout { + // top-left corner, includes border of current element + // (0, 0) represents top-left corner of a parent (inner corner if parent has border too) + // + // e.g. if parent layout and current layout have border 10 and current layout is at (0, 0) then + // their top and left edges will be next to each other without overlapping pub top: f32, pub left: f32, + + // size on the output texture, includes border pub width: f32, pub height: f32, + pub rotation_degrees: f32, /// scale will affect content/children, but not the properties of current layout like - /// top/left/widht/height + /// top/left/width/height pub scale_x: f32, pub scale_y: f32, /// Crop is applied before scaling. + /// + /// If you need to scale before cropping use 2 nested layouts: + /// - child to scale + /// - parent to crop + /// + /// Depending on content + /// - For texture it describes what chunk of texture should be cut and stretched on + /// width/height + /// - For layout it cuts of part of it (defined in coordinates system of this component) pub crop: Option, + /// Everything outside this mask should not be rendered. Coordinates are relative to + /// the layouts top-left corner (and not to the 0,0 point that top-left are defined in) + pub mask: Option, pub content: LayoutContent, + pub border_width: f32, + pub border_color: RGBAColor, + pub border_radius: BorderRadius, + pub box_shadow: Vec, + pub(crate) children: Vec, /// Describes how many children of this component are nodes. This value also /// counts `layout` if its content is a `LayoutContent::ChildNode`. @@ -97,7 +154,6 @@ impl LayoutNode { Self { layout_provider, shader, - params: ParamsBuffer::new(ctx.wgpu_ctx, vec![]), } } @@ -113,39 +169,14 @@ impl LayoutNode { .map(|node_texture| node_texture.resolution()) .collect(); let output_resolution = self.layout_provider.resolution(pts); - let layouts = self - .layout_provider - .layouts(pts, &input_resolutions) - .flatten(&input_resolutions, output_resolution); - - let params: Vec = layouts - .iter() - .map(|layout| { - let (is_texture, background_color, input_resolution) = match layout.content { - RenderLayoutContent::ChildNode { index, .. } => ( - 1, - RGBAColor(0, 0, 0, 0), - *input_resolutions.get(index).unwrap_or(&None), - ), - RenderLayoutContent::Color(color) => (0, color, None), - }; - - LayoutNodeParams { - is_texture, - background_color, - transform_vertices_matrix: layout - .vertices_transformation_matrix(&output_resolution), - transform_texture_coords_matrix: layout - .texture_coords_transformation_matrix(&input_resolution), - } - }) - .collect(); - self.params.update(params, ctx.wgpu_ctx); + let layouts = self.layout_provider.layouts(pts, &input_resolutions); + let layouts = layouts.flatten(&input_resolutions, output_resolution); let textures: Vec> = layouts .iter() .map(|layout| match layout.content { - RenderLayoutContent::Color(_) => None, + RenderLayoutContent::BoxShadow { .. } => None, + RenderLayoutContent::Color { .. } => None, RenderLayoutContent::ChildNode { index, .. } => match sources.get(index) { Some(node_texture) => Some(*node_texture), None => { @@ -158,7 +189,7 @@ impl LayoutNode { let target = target.ensure_size(ctx.wgpu_ctx, output_resolution); self.shader - .render(ctx.wgpu_ctx, self.params.bind_group(), &textures, target); + .render(ctx.wgpu_ctx, output_resolution, layouts, &textures, target); } } @@ -176,9 +207,14 @@ impl NestedLayout { scale_x: 1.0, scale_y: 1.0, crop: None, + mask: None, content: LayoutContent::None, children: vec![], child_nodes_count, + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + border_radius: BorderRadius::ZERO, + box_shadow: vec![], } } } diff --git a/compositor_render/src/transformations/layout/apply_layouts.wgsl b/compositor_render/src/transformations/layout/apply_layouts.wgsl index 7bfae09a1..8a2b5bad7 100644 --- a/compositor_render/src/transformations/layout/apply_layouts.wgsl +++ b/compositor_render/src/transformations/layout/apply_layouts.wgsl @@ -1,51 +1,372 @@ struct VertexInput { + // position in clip space [-1, -1] (bottom-left) X [1, 1] (top-right) @location(0) position: vec3, + // texture coordinates in texture coordiantes [0, 0] (top-left) X [1, 1] (bottom-right) @location(1) tex_coords: vec2, } struct VertexOutput { + // position in output in pixel coordinates [0, 0] (top-left) X [output_resolution.x, output_resolution.y] (bottom-right) @builtin(position) position: vec4, + // texture coordinates in texture coordiantes [0, 0] (top-left) X [1, 1] (bottom-right) @location(0) tex_coords: vec2, + // Position relative to center of the rectangle in [-rect_width/2, rect_width/2] X [-rect_height/2, height/2] + @location(2) center_position: vec2, } +struct BoxShadowParams { + border_radius: vec4, + color: vec4, + top: f32, + left: f32, + width: f32, + height: f32, + rotation_degrees: f32, + blur_radius: f32, +} + +struct TextureParams { + border_radius: vec4, + border_color: vec4, + // position + top: f32, + left: f32, + width: f32, + height: f32, + // texture crop + crop_top: f32, + crop_left: f32, + crop_width: f32, + crop_height: f32, + + rotation_degrees: f32, + // border size in pixels + border_width: f32, +} + +struct ColorParams { + border_radius: vec4, + border_color: vec4, + color: vec4, + + top: f32, + left: f32, + width: f32, + height: f32, -struct Layout { - vertices_transformation: mat4x4, - texture_coord_transformation: mat4x4, - color: vec4, // used only when is_texture == 0 - is_texture: u32, // 0 -> color, 1 -> texture + rotation_degrees: f32, + border_width: f32, } +struct ParentMask { + radius: vec4, + top: f32, + left: f32, + width: f32, + height: f32, +} + +struct LayoutInfo { + // 0 -> Texture, 1 -> Color, 2 -> BoxShadow + layout_type: u32, + index: u32, + masks_len: u32 +} + + @group(0) @binding(0) var texture: texture_2d; -@group(1) @binding(0) var layouts: array; -@group(2) @binding(0) var sampler_: sampler; -var layout_id: u32; +@group(1) @binding(0) var output_resolution: vec4; +@group(1) @binding(1) var texture_params: array; +@group(1) @binding(2) var color_params: array; +@group(1) @binding(3) var box_shadow_params: array; + +@group(2) @binding(0) var masks: array; + +@group(3) @binding(0) var sampler_: sampler; + +var layout_info: LayoutInfo; + +fn rotation_matrix(rotation: f32) -> mat4x4 { + // wgsl is column-major + let angle = radians(rotation); + let c = cos(angle); + let s = sin(angle); + return mat4x4( + vec4(c, s, 0.0, 0.0), + vec4(-s, c, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + +fn scale_matrix(scale: vec2) -> mat4x4 { + return mat4x4( + vec4(scale.x, 0.0, 0.0, 0.0), + vec4(0.0, scale.y, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(0.0, 0.0, 0.0, 1.0) + ); +} + + +fn translation_matrix(translation: vec2) -> mat4x4 { + return mat4x4( + vec4(1.0, 0.0, 0.0, 0.0), + vec4(0.0, 1.0, 0.0, 0.0), + vec4(0.0, 0.0, 1.0, 0.0), + vec4(translation, 0.0, 1.0) + ); +} + +fn vertices_transformation_matrix(left: f32, top: f32, width: f32, height: f32, rotation: f32) -> mat4x4 { + let scale_to_size = vec2( + width / output_resolution.x, + height / output_resolution.y + ); + let scale_to_pixels = vec2( + output_resolution.x / 2.0, + output_resolution.y / 2.0 + ); + let scale_to_clip_space = vec2( + 1.0 / scale_to_pixels.x, + 1.0 / scale_to_pixels.y + ); + + let scale_to_pixels_mat = scale_matrix(scale_to_pixels * scale_to_size); + let scale_to_clip_space_mat = scale_matrix(scale_to_clip_space); + + let left_border_x = -(output_resolution.x / 2.0); + let distance_left_to_middle = left + width / 2.0; + let top_border_y = output_resolution.y / 2.0; + let distance_top_to_middle = top + height / 2.0; + let translation = vec2( + left_border_x + distance_left_to_middle, + top_border_y - distance_top_to_middle + ); + + let translation_mat = translation_matrix(translation); + let rotation_mat = rotation_matrix(rotation); + + return scale_to_clip_space_mat * translation_mat * rotation_mat * scale_to_pixels_mat; +} + +fn texture_coord_transformation_matrix(crop_left: f32, crop_top: f32, crop_width: f32, crop_height: f32) -> mat4x4 { + let dim = textureDimensions(texture); + let scale = vec2( + crop_width / f32(dim.x), + crop_height / f32(dim.y), + ); + + let translation = vec2( + crop_left / f32(dim.x), + crop_top / f32(dim.y), + ); + + return translation_matrix(translation) * scale_matrix(scale); +} @vertex fn vs_main(input: VertexInput) -> VertexOutput { var output: VertexOutput; - let vertices_transformation_matrix: mat4x4 = layouts[layout_id].vertices_transformation; - let texture_coord_transformation_matrix: mat4x4 = layouts[layout_id].texture_coord_transformation; + switch (layout_info.layout_type) { + // texture + case 0u: { + let vertices_transformation = vertices_transformation_matrix( + texture_params[layout_info.index].left, + texture_params[layout_info.index].top, + texture_params[layout_info.index].width, + texture_params[layout_info.index].height, + texture_params[layout_info.index].rotation_degrees + ); + let texture_transformation = texture_coord_transformation_matrix( + texture_params[layout_info.index].crop_left, + texture_params[layout_info.index].crop_top, + texture_params[layout_info.index].crop_width, + texture_params[layout_info.index].crop_height + ); + + output.position = vertices_transformation * vec4(input.position, 1.0); + output.tex_coords = (texture_transformation * vec4(input.tex_coords, 0.0, 1.0)).xy; + let rect_size = vec2(texture_params[layout_info.index].width, texture_params[layout_info.index].height); + output.center_position = input.position.xy / 2.0 * rect_size; + } + // color + case 1u: { + let vertices_transformation = vertices_transformation_matrix( + color_params[layout_info.index].left, + color_params[layout_info.index].top, + color_params[layout_info.index].width, + color_params[layout_info.index].height, + color_params[layout_info.index].rotation_degrees + ); + output.position = vertices_transformation * vec4(input.position, 1.0); + output.tex_coords = input.tex_coords; + let rect_size = vec2(color_params[layout_info.index].width, color_params[layout_info.index].height); + output.center_position = input.position.xy / 2.0 * rect_size; + } + // box shadow + case 2u: { + let width = box_shadow_params[layout_info.index].width + 2.0 * box_shadow_params[layout_info.index].blur_radius; + let height = box_shadow_params[layout_info.index].height + 2.0 * box_shadow_params[layout_info.index].blur_radius; - output.position = vec4(input.position, 1.0) * vertices_transformation_matrix; - output.tex_coords = (vec4(input.tex_coords, 0.0, 1.0) * texture_coord_transformation_matrix).xy; + let vertices_transformation = vertices_transformation_matrix( + box_shadow_params[layout_info.index].left - box_shadow_params[layout_info.index].blur_radius, + box_shadow_params[layout_info.index].top - box_shadow_params[layout_info.index].blur_radius, + width, + height, + box_shadow_params[layout_info.index].rotation_degrees + ); + output.position = vertices_transformation * vec4(input.position, 1.0); + output.tex_coords = input.tex_coords; + let rect_size = vec2(width, height); + output.center_position = input.position.xy / 2.0 * rect_size; + } + default {} + } return output; } +// Signed distance function for rounded rectangle https://iquilezles.org/articles/distfunctions +// adapted from https://www.shadertoy.com/view/4llXD7 +// Distance from outside is positive and inside it is negative +// +// dist - signed distance from the center of the rectangle in pixels +// size - size of the rectangle in pixels +// radius - radius of the corners in pixels [top-left, top-right, bottom-right, bottom-left] +// rotation - rotation of the rectangle in degrees +// WARNING - it doesn't work when border radius is > min(size.x, size.y) / 2 +fn roundedRectSDF(dist: vec2, size: vec2, radius: vec4, rotation: f32) -> f32 { + let half_size = size / 2.0; + + // wierd hack to get the radius of the nearest corner stored in r.x + var r: vec2 = vec2(0.0, 0.0); + r = select(radius.yz, radius.xw, dist.x < 0.0); + r.x = select(r.x, r.y, dist.y < 0.0); + + let q = abs(dist) - half_size + r.x; + return min(max(q.x, q.y), 0.0) + length(max(q, vec2(0.0, 0.0))) - r.x; +} + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { - let current_layout = layouts[layout_id]; + let transparent = vec4(1.0, 1.0, 1.0, 0.0); - // sampling can't be conditional, so in case of plane_id == -1 - // sample textures[0], but ignore the result. - if (current_layout.is_texture == 0u) { - return current_layout.color; + var mask_alpha = 1.0; + + for (var i = 0; i < i32(layout_info.masks_len); i++) { + let radius = masks[i].radius; + let top = masks[i].top; + let left = masks[i].left; + let width = masks[i].width; + let height = masks[i].height; + let size = vec2(width, height); + + let distance = roundedRectSDF( + vec2(left, top) + (size / 2.0) - input.position.xy, + size, + radius, + 0.0, + ); + mask_alpha = mask_alpha * smoothstep(-0.5, 0.5 , -distance); } - // clamp transparent, when crop > input texture - let is_inside: f32 = round(f32(input.tex_coords.x < 1.0 && input.tex_coords.x > 0.0 && input.tex_coords.y > 0.0 && input.tex_coords.y < 1.0)); - return is_inside * textureSample(texture, sampler_, input.tex_coords); + switch layout_info.layout_type { + case 0u: { + let sample = textureSample(texture, sampler_, input.tex_coords); + + let width = texture_params[layout_info.index].width; + let height = texture_params[layout_info.index].height; + let border_radius = texture_params[layout_info.index].border_radius; + let rotation_degrees = texture_params[layout_info.index].rotation_degrees; + let border_width = texture_params[layout_info.index].border_width; + let border_color = texture_params[layout_info.index].border_color; + + let size = vec2(width, height); + let edge_distance = -roundedRectSDF( + input.center_position, + size, + border_radius, + rotation_degrees + ); + + if (border_width < 1.0) { + let content_alpha = smoothstep(-0.5, 0.5, edge_distance); + return vec4(sample.rgb, sample.a * content_alpha * mask_alpha); + } else if (mask_alpha < 0.01) { + return vec4(0, 0, 0, 0); + } else { + if (edge_distance > border_width / 2.0) { + // border <-> content + let border_alpha = smoothstep(border_width - 0.5, border_width + 0.5, edge_distance); + let border_or_content = mix(border_color, sample, border_alpha); + return vec4(border_or_content.rgb, border_or_content.a * mask_alpha); + } else { + // border <-> outside + let content_alpha = smoothstep(-0.5, 0.5, edge_distance); + return vec4(border_color.rgb, border_color.a * content_alpha * mask_alpha); + } + } + } + case 1u: { + let color = color_params[layout_info.index].color; + + let width = color_params[layout_info.index].width; + let height = color_params[layout_info.index].height; + let border_radius = color_params[layout_info.index].border_radius; + let rotation_degrees = color_params[layout_info.index].rotation_degrees; + let border_width = color_params[layout_info.index].border_width; + let border_color = color_params[layout_info.index].border_color; + + let size = vec2(width, height); + let edge_distance = -roundedRectSDF( + input.center_position, + size, + border_radius, + rotation_degrees + ); + + if (border_width < 1.0) { + let content_alpha = smoothstep(-0.5, 0.5, edge_distance); + return vec4(color.rgb, color.a * content_alpha * mask_alpha); + } else { + if (edge_distance > border_width / 2.0) { + // border <-> content + let border_alpha = smoothstep(border_width, border_width + 1.0, edge_distance); + let border_or_content = mix(border_color, color, border_alpha); + return vec4(border_or_content.rgb, border_or_content.a * mask_alpha); + } else { + // border <-> outside + let content_alpha = smoothstep(-0.5, 0.5, edge_distance); + return vec4(border_color.rgb, border_color.a * content_alpha * mask_alpha); + } + } + } + case 2u: { + let color = box_shadow_params[layout_info.index].color; + + let width = box_shadow_params[layout_info.index].width; + let height = box_shadow_params[layout_info.index].height; + let border_radius = box_shadow_params[layout_info.index].border_radius; + let rotation_degrees = box_shadow_params[layout_info.index].rotation_degrees; + let blur_radius = box_shadow_params[layout_info.index].blur_radius; + + let size = vec2(width, height); + let edge_distance = -roundedRectSDF( + input.center_position, + size, + border_radius, + rotation_degrees + ); + + let blur_alpha = smoothstep(-blur_radius / 2.0, blur_radius / 2.0, edge_distance) * mask_alpha; + + return vec4(color.rgb, color.a * blur_alpha); + } + default { + return vec4(0.0, 0.0, 0.0, 0.0); + } + } } diff --git a/compositor_render/src/transformations/layout/flatten.rs b/compositor_render/src/transformations/layout/flatten.rs index 131a623fa..33abd9fe8 100644 --- a/compositor_render/src/transformations/layout/flatten.rs +++ b/compositor_render/src/transformations/layout/flatten.rs @@ -1,6 +1,10 @@ +use std::{iter, mem}; + use crate::{scene::RGBAColor, Resolution}; -use super::{Crop, LayoutContent, NestedLayout, RenderLayout, RenderLayoutContent}; +use super::{ + BoxShadow, Crop, LayoutContent, Mask, NestedLayout, RenderLayout, RenderLayoutContent, +}; impl NestedLayout { pub(super) fn flatten( @@ -8,14 +12,20 @@ impl NestedLayout { input_resolutions: &[Option], resolution: Resolution, ) -> Vec { - let layouts = self.inner_flatten(0); - layouts + let (shadow, layouts) = self.inner_flatten(0, vec![]); + shadow .into_iter() + .chain(layouts) .filter(|layout| Self::should_render(layout, input_resolutions, resolution)) + .map(NestedLayout::fix_final_render_layout) .collect() } - fn inner_flatten(mut self, child_index_offset: usize) -> Vec { + fn inner_flatten( + mut self, + child_index_offset: usize, + parent_masks: Vec, + ) -> (Vec, Vec) { let mut child_index_offset = child_index_offset; if let LayoutContent::ChildNode { index, size } = self.content { self.content = LayoutContent::ChildNode { @@ -24,20 +34,90 @@ impl NestedLayout { }; child_index_offset += 1 } - let layout = self.render_layout(); - let children: Vec<_> = std::mem::take(&mut self.children) + let layout = self.render_layout(&parent_masks); + // It is separated because box shadows of all siblings need to be rendered before + // this layout and it's siblings + let box_shadow_layouts = self + .box_shadow + .iter() + .map(|shadow| self.box_shadow_layout(shadow, &parent_masks)) + .collect(); + + let parent_masks = match &self.mask { + Some(mask) => parent_masks + .iter() + .chain(iter::once(mask)) + .cloned() + .collect(), + None => parent_masks.clone(), + }; + let parent_masks = self.child_parent_masks(&parent_masks); + + let (children_shadow, children_layouts): (Vec<_>, Vec<_>) = + std::mem::take(&mut self.children) + .into_iter() + .map(|child| { + let child_nodes_count = child.child_nodes_count; + let (shadows, layouts) = + child.inner_flatten(child_index_offset, parent_masks.clone()); + child_index_offset += child_nodes_count; + (shadows, layouts) + }) + .unzip(); + let children_shadow = children_shadow .into_iter() - .flat_map(|child| { - let child_nodes_count = child.child_nodes_count; - let layouts = child.inner_flatten(child_index_offset); - child_index_offset += child_nodes_count; - layouts - }) + .flatten() .map(|l| self.flatten_child(l)) .collect(); - [vec![layout], children].concat() + let children_layouts = children_layouts + .into_iter() + .flatten() + .map(|l| self.flatten_child(l)) + .collect(); + + ( + box_shadow_layouts, + [vec![layout], children_shadow, children_layouts].concat(), + ) + } + + // Final pass on each render layout, it applies following modifications: + // - If border_width is between 0 and 1 set it to 1. + // - Remove masks that don't do anything + fn fix_final_render_layout(mut layout: RenderLayout) -> RenderLayout { + fn filter_mask(layout: &RenderLayout, mask: Mask) -> Option { + let max_top_border = f32::max(mask.radius.top_left, mask.radius.top_right); + let max_bottom_border = f32::max(mask.radius.bottom_left, mask.radius.bottom_right); + let max_left_border = f32::max(mask.radius.top_left, mask.radius.bottom_left); + let max_right_border = f32::max(mask.radius.top_right, mask.radius.bottom_right); + let should_skip = mask.top + max_top_border <= layout.top + && mask.left + max_left_border <= layout.left + && mask.left + mask.width - max_right_border >= layout.left + layout.width + && mask.top + mask.height - max_bottom_border >= layout.top + layout.height; + match should_skip { + true => None, + false => Some(mask), + } + } + match &mut layout.content { + RenderLayoutContent::Color { border_width, .. } + | RenderLayoutContent::ChildNode { border_width, .. } => { + if *border_width < 1.0 { + *border_width = 0.0 + } + } + _ => (), + }; + layout.masks = mem::take(&mut layout.masks) + .into_iter() + .filter_map(|mask| filter_mask(&layout, mask)) + .collect(); + layout } + // Decides if layout will affect the output of the stream, if not this layout will not be + // passed to the shader. + // Layouts are in absolute units at this point. fn should_render( layout: &RenderLayout, input_resolutions: &[Option], @@ -51,9 +131,19 @@ impl NestedLayout { return false; } match &layout.content { - RenderLayoutContent::Color(RGBAColor(_, _, _, 0)) => false, - RenderLayoutContent::Color(_) => true, - RenderLayoutContent::ChildNode { crop, index } => { + RenderLayoutContent::Color { + color: RGBAColor(_, _, _, 0), + border_color: RGBAColor(_, _, _, border_alpha), + border_width, + } => *border_alpha != 0 || *border_width > 0.0, + RenderLayoutContent::Color { .. } => true, + RenderLayoutContent::ChildNode { + crop, + index, + border_color: RGBAColor(_, _, _, _), + border_width: _, + } => { + // TODO: handle a case when only border is visible (currently impossible) let size = input_resolutions.get(*index).copied().flatten(); if let Some(size) = size { if crop.left > size.width as f32 || crop.top > size.height as f32 { @@ -65,18 +155,59 @@ impl NestedLayout { } true } + RenderLayoutContent::BoxShadow { + color: RGBAColor(_, _, _, 0), + .. + } => false, + RenderLayoutContent::BoxShadow { .. } => true, } } - fn flatten_child(&self, layout: RenderLayout) -> RenderLayout { + // parent_masks - in self coordinates + fn flatten_child(&self, child: RenderLayout) -> RenderLayout { + // scale factor used if we need to scale something that can't be + // scaled separately for horizontal and vertical direction. + let unified_scale = f32::min(self.scale_x, self.scale_y); + match &self.crop { None => RenderLayout { - top: self.top + (layout.top * self.scale_y), - left: self.left + (layout.left * self.scale_x), - width: layout.width * self.scale_x, - height: layout.height * self.scale_y, - rotation_degrees: layout.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct - content: layout.content, + top: self.top + (child.top * self.scale_y), + left: self.left + (child.left * self.scale_x), + width: child.width * self.scale_x, + height: child.height * self.scale_y, + rotation_degrees: child.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct + content: match child.content { + RenderLayoutContent::Color { + color, + border_color, + border_width, + } => RenderLayoutContent::Color { + color, + border_color, + border_width: border_width * unified_scale, + }, + RenderLayoutContent::ChildNode { + index, + border_color, + border_width, + crop, + } => RenderLayoutContent::ChildNode { + index, + border_color, + border_width: border_width * unified_scale, + crop, + }, + RenderLayoutContent::BoxShadow { color, blur_radius } => { + RenderLayoutContent::BoxShadow { + color, + blur_radius: blur_radius * unified_scale, + } + } + }, + // TODO: This will not work correctly for layouts that are not proportionally + // scaled + border_radius: child.border_radius * unified_scale, + masks: self.parent_parent_masks(&child.masks), }, Some(crop) => { // Below values are only correct if `crop` is in the same coordinate @@ -86,37 +217,49 @@ impl NestedLayout { // Value in coordinates of `self` (relative to it's top-left corner). Represents // a position after cropping and translated back to (layout.top, layout.left). - let cropped_top = f32::max(layout.top - crop.top, 0.0); - let cropped_left = f32::max(layout.left - crop.left, 0.0); - let cropped_bottom = f32::min(layout.top + layout.height - crop.top, crop.height); - let cropped_right = f32::min(layout.left + layout.width - crop.left, crop.width); + let cropped_top = f32::max(child.top - crop.top, 0.0); + let cropped_left = f32::max(child.left - crop.left, 0.0); + let cropped_bottom = f32::min(child.top + child.height - crop.top, crop.height); + let cropped_right = f32::min(child.left + child.width - crop.left, crop.width); let cropped_width = cropped_right - cropped_left; let cropped_height = cropped_bottom - cropped_top; - match layout.content { - RenderLayoutContent::Color(color) => { + match child.content.clone() { + RenderLayoutContent::Color { + color, + border_color, + border_width, + } => { RenderLayout { top: self.top + (cropped_top * self.scale_y), left: self.left + (cropped_left * self.scale_x), width: cropped_width * self.scale_x, height: cropped_height * self.scale_y, - rotation_degrees: layout.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct - content: RenderLayoutContent::Color(color), + rotation_degrees: child.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct + content: RenderLayoutContent::Color { + color, + border_color, + border_width: border_width * unified_scale, + }, + border_radius: child.border_radius * unified_scale, + masks: self.parent_parent_masks(&child.masks), } } RenderLayoutContent::ChildNode { index, crop: child_crop, + border_color, + border_width, } => { // Calculate how much top/left coordinates changed when cropping. It represents // how much was removed in layout coordinates. Ignore the change of a position that // was a result of a translation after cropping. - let top_diff = f32::max(crop.top - layout.top, 0.0); - let left_diff = f32::max(crop.left - layout.left, 0.0); + let top_diff = f32::max(crop.top - child.top, 0.0); + let left_diff = f32::max(crop.left - child.left, 0.0); // Factor to translate from `layout` coordinates to child node coord. // The same factor holds for translations from `self.layout`. - let horizontal_scale_factor = child_crop.width / layout.width; - let vertical_scale_factor = child_crop.height / layout.height; + let horizontal_scale_factor = child_crop.width / child.width; + let vertical_scale_factor = child_crop.height / child.height; let crop = Crop { top: child_crop.top + (top_diff * vertical_scale_factor), @@ -130,8 +273,30 @@ impl NestedLayout { left: self.left + (cropped_left * self.scale_x), width: cropped_width * self.scale_x, height: cropped_height * self.scale_y, - rotation_degrees: layout.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct - content: RenderLayoutContent::ChildNode { index, crop }, + rotation_degrees: child.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct + content: RenderLayoutContent::ChildNode { + index, + crop, + border_color, + border_width, + }, + border_radius: child.border_radius * unified_scale, + masks: self.parent_parent_masks(&child.masks), + } + } + RenderLayoutContent::BoxShadow { color, blur_radius } => { + RenderLayout { + top: self.top + (cropped_top * self.scale_y), + left: self.left + (cropped_left * self.scale_x), + width: cropped_width * self.scale_x, + height: cropped_height * self.scale_y, + rotation_degrees: child.rotation_degrees + self.rotation_degrees, // TODO: not exactly correct + content: RenderLayoutContent::BoxShadow { + color, + blur_radius: blur_radius * unified_scale, + }, + border_radius: child.border_radius * unified_scale, + masks: self.parent_parent_masks(&child.masks), } } } @@ -139,7 +304,11 @@ impl NestedLayout { } } - fn render_layout(&self) -> RenderLayout { + /// Calculate RenderLayout for self (without children) + /// Resulting layout is in coordinates: + /// - relative self's parent top-left corner. + /// - before parent scaling is applied + fn render_layout(&self, parent_masks: &[Mask]) -> RenderLayout { RenderLayout { top: self.top, left: self.left, @@ -147,7 +316,11 @@ impl NestedLayout { height: self.height, rotation_degrees: self.rotation_degrees, content: match self.content { - LayoutContent::Color(color) => RenderLayoutContent::Color(color), + LayoutContent::Color(color) => RenderLayoutContent::Color { + color, + border_color: self.border_color, + border_width: self.border_width, + }, LayoutContent::ChildNode { index, size } => RenderLayoutContent::ChildNode { index, crop: Crop { @@ -156,9 +329,62 @@ impl NestedLayout { width: size.width, height: size.height, }, + border_color: self.border_color, + border_width: self.border_width, + }, + LayoutContent::None => RenderLayoutContent::Color { + color: RGBAColor(0, 0, 0, 0), + border_color: self.border_color, + border_width: self.border_width, }, - LayoutContent::None => RenderLayoutContent::Color(RGBAColor(0, 0, 0, 0)), }, + border_radius: self.border_radius, + masks: parent_masks.to_vec(), } } + + /// calculate RenderLayout for one of self box shadows + fn box_shadow_layout(&self, box_shadow: &BoxShadow, parent_masks: &[Mask]) -> RenderLayout { + RenderLayout { + top: self.top + box_shadow.offset_y, + left: self.left + box_shadow.offset_x, + width: self.width, + height: self.height, + rotation_degrees: self.rotation_degrees, // TODO: this is incorrect + border_radius: self.border_radius + (box_shadow.blur_radius / 2.0), + content: RenderLayoutContent::BoxShadow { + color: box_shadow.color, + blur_radius: box_shadow.blur_radius, + }, + masks: parent_masks.to_vec(), + } + } + + /// Calculate ParentMasks in coordinates of child NestedLayout. + fn child_parent_masks(&self, masks: &[Mask]) -> Vec { + masks + .iter() + .map(|mask| Mask { + radius: mask.radius / f32::min(self.scale_x, self.scale_y), + top: (mask.top - self.top) / self.scale_y, + left: (mask.left - self.left) / self.scale_x, + width: mask.width / self.scale_x, + height: mask.height / self.scale_y, + }) + .collect() + } + + /// Translates parent mask from child coordinates to parent. Reverse operation to `child_parent_masks`. + fn parent_parent_masks(&self, masks: &[Mask]) -> Vec { + masks + .iter() + .map(|mask| Mask { + radius: mask.radius * f32::min(self.scale_x, self.scale_y), + top: (mask.top * self.scale_y) + self.top, + left: (mask.left * self.scale_x) + self.left, + width: mask.width * self.scale_x, + height: mask.height * self.scale_y, + }) + .collect() + } } diff --git a/compositor_render/src/transformations/layout/params.rs b/compositor_render/src/transformations/layout/params.rs index 1c3fc7474..18f04ddd1 100644 --- a/compositor_render/src/transformations/layout/params.rs +++ b/compositor_render/src/transformations/layout/params.rs @@ -1,126 +1,366 @@ -use nalgebra_glm::Mat4; -use wgpu::util::DeviceExt; +use tracing::error; +use wgpu::{ + util::{BufferInitDescriptor, DeviceExt}, + BindGroupLayoutDescriptor, BufferUsages, +}; -use crate::{scene::RGBAColor, wgpu::WgpuCtx}; +use crate::{scene::RGBAColor, wgpu::WgpuCtx, Resolution}; -#[derive(Debug, Clone)] -pub(super) struct LayoutNodeParams { - pub(super) transform_vertices_matrix: Mat4, - pub(super) transform_texture_coords_matrix: Mat4, - pub(super) is_texture: u32, - pub(super) background_color: RGBAColor, +use super::{BorderRadius, RenderLayout}; + +const MAX_MASKS: usize = 20; +const MAX_LAYOUTS_COUNT: usize = 100; +const TEXTURE_PARAMS_BUFFER_SIZE: usize = MAX_LAYOUTS_COUNT * 80; +const COLOR_PARAMS_SIZE: usize = MAX_LAYOUTS_COUNT * 80; +const BOX_SHADOW_PARAMS_SIZE: usize = MAX_LAYOUTS_COUNT * 80; + +#[derive(Debug)] +pub struct LayoutInfo { + pub layout_type: u32, + pub index: u32, + pub masks_len: u32, } -impl Default for LayoutNodeParams { - fn default() -> Self { - Self { - transform_vertices_matrix: Mat4::identity(), - transform_texture_coords_matrix: Mat4::identity(), - is_texture: 0, - background_color: RGBAColor(0, 0, 0, 0), - } +impl LayoutInfo { + pub fn to_bytes(&self) -> [u8; 16] { + let mut result = [0u8; 16]; + result[0..4].copy_from_slice(&self.layout_type.to_le_bytes()); + result[4..8].copy_from_slice(&self.index.to_le_bytes()); + result[8..12].copy_from_slice(&self.masks_len.to_le_bytes()); + result } } -pub(super) struct ParamsBuffer { - bind_group: wgpu::BindGroup, - buffer: wgpu::Buffer, - content: bytes::Bytes, +#[derive(Debug)] +pub struct ParamsBindGroups { + pub bind_group_1: wgpu::BindGroup, + pub bind_group_1_layout: wgpu::BindGroupLayout, + output_resolution_buffer: wgpu::Buffer, + texture_params_buffer: wgpu::Buffer, + color_params_buffer: wgpu::Buffer, + box_shadow_params_buffer: wgpu::Buffer, + pub bind_groups_2: Vec<(wgpu::BindGroup, wgpu::Buffer)>, + pub bind_group_2_layout: wgpu::BindGroupLayout, } -impl ParamsBuffer { - pub fn new(wgpu_ctx: &WgpuCtx, params: Vec) -> Self { - let mut content = Self::shader_buffer_content(¶ms); - if content.is_empty() { - content = bytes::Bytes::copy_from_slice(&[0]); - } +impl ParamsBindGroups { + pub fn new(ctx: &WgpuCtx) -> ParamsBindGroups { + let output_resolution_buffer = create_buffer(ctx, 16); + let texture_params_buffer = create_buffer(ctx, TEXTURE_PARAMS_BUFFER_SIZE); + let color_params_buffer = create_buffer(ctx, COLOR_PARAMS_SIZE); + let box_shadow_params_buffer = create_buffer(ctx, BOX_SHADOW_PARAMS_SIZE); - let buffer = wgpu_ctx + let bind_group_1_layout = ctx .device - .create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("params buffer"), - usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, - contents: &content, + .create_bind_group_layout(&BindGroupLayoutDescriptor { + label: Some("Bind group 1 layout"), + entries: &[ + wgpu::BindGroupLayoutEntry { + binding: 0, + count: None, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + }, + wgpu::BindGroupLayoutEntry { + binding: 1, + count: None, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + }, + wgpu::BindGroupLayoutEntry { + binding: 2, + count: None, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + }, + wgpu::BindGroupLayoutEntry { + binding: 3, + count: None, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + }, + ], }); - let bind_group = wgpu_ctx - .device - .create_bind_group(&wgpu::BindGroupDescriptor { - label: Some("params bind group"), - layout: &wgpu_ctx.uniform_bgl, + let bind_group_1 = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("Bind group 1"), + layout: &bind_group_1_layout, + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: output_resolution_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: texture_params_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: color_params_buffer.as_entire_binding(), + }, + wgpu::BindGroupEntry { + binding: 3, + resource: box_shadow_params_buffer.as_entire_binding(), + }, + ], + }); + + let bind_group_2_layout = + ctx.device + .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("Bind group 2 layout"), + entries: &[wgpu::BindGroupLayoutEntry { + binding: 0, + visibility: wgpu::ShaderStages::VERTEX_FRAGMENT, + ty: wgpu::BindingType::Buffer { + ty: wgpu::BufferBindingType::Uniform, + has_dynamic_offset: false, + min_binding_size: None, + }, + count: None, + }], + }); + + let mut bind_groups_2 = Vec::with_capacity(100); + for _ in 0..100 { + let buffer = create_buffer(ctx, 20 * 32); + + let bind_group_2 = ctx.device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("Bind group 2"), + layout: &bind_group_2_layout, entries: &[wgpu::BindGroupEntry { binding: 0, resource: buffer.as_entire_binding(), }], }); + bind_groups_2.push((bind_group_2, buffer)); + } Self { - bind_group, - buffer, - content, + bind_group_1, + output_resolution_buffer, + texture_params_buffer, + color_params_buffer, + box_shadow_params_buffer, + bind_groups_2, + bind_group_1_layout, + bind_group_2_layout, } } - pub fn bind_group(&self) -> &wgpu::BindGroup { - &self.bind_group - } - - pub fn update(&mut self, params: Vec, wgpu_ctx: &WgpuCtx) { - let content = Self::shader_buffer_content(¶ms); - if self.content.len() != content.len() { - *self = Self::new(wgpu_ctx, params); + pub fn update( + &self, + ctx: &WgpuCtx, + output_resolution: Resolution, + layouts: Vec, + ) -> Vec { + if layouts.len() > MAX_LAYOUTS_COUNT { + error!( + "Max layouts count ({}) exceeded ({}). Skipping rendering some of them.", + MAX_LAYOUTS_COUNT, + layouts.len() + ) } - if self.content != content { - wgpu_ctx.queue.write_buffer(&self.buffer, 0, &content); + let mut output_resolution_bytes = [0u8; 8]; + output_resolution_bytes[0..4] + .copy_from_slice(&(output_resolution.width as f32).to_le_bytes()); + output_resolution_bytes[4..8] + .copy_from_slice(&(output_resolution.height as f32).to_le_bytes()); + + ctx.queue + .write_buffer(&self.output_resolution_buffer, 0, &output_resolution_bytes); + + let mut layout_infos = Vec::new(); + + let mut texture_params = Vec::new(); + let mut color_params = Vec::new(); + let mut box_shadow_params = Vec::new(); + + for (index, layout) in layouts.iter().enumerate().take(MAX_LAYOUTS_COUNT) { + let RenderLayout { + top, + left, + width, + height, + rotation_degrees, + border_radius, + masks, + content, + } = layout; + let border_radius_bytes = borders_radius_to_bytes(*border_radius); + + match content { + super::RenderLayoutContent::Color { + color, + border_color, + border_width, + } => { + let layout_info = LayoutInfo { + layout_type: 1, + index: color_params.len() as u32, + masks_len: masks.len() as u32, + }; + let mut color_params_bytes = [0u8; 80]; + color_params_bytes[0..16].copy_from_slice(&border_radius_bytes); + color_params_bytes[16..32].copy_from_slice(&color_to_bytes(*border_color)); + color_params_bytes[32..48].copy_from_slice(&color_to_bytes(*color)); + color_params_bytes[48..52].copy_from_slice(&top.to_le_bytes()); + color_params_bytes[52..56].copy_from_slice(&left.to_le_bytes()); + color_params_bytes[56..60].copy_from_slice(&width.to_le_bytes()); + color_params_bytes[60..64].copy_from_slice(&height.to_le_bytes()); + color_params_bytes[64..68].copy_from_slice(&rotation_degrees.to_le_bytes()); + color_params_bytes[68..72].copy_from_slice(&border_width.to_le_bytes()); + color_params.push(color_params_bytes); + layout_infos.push(layout_info); + } + super::RenderLayoutContent::ChildNode { + index: _, + crop, + border_color, + border_width, + } => { + let layout_info = LayoutInfo { + layout_type: 0, + index: texture_params.len() as u32, + masks_len: masks.len() as u32, + }; + let mut texture_params_bytes = [0u8; 80]; + texture_params_bytes[0..16].copy_from_slice(&border_radius_bytes); + texture_params_bytes[16..32].copy_from_slice(&color_to_bytes(*border_color)); + texture_params_bytes[32..36].copy_from_slice(&top.to_le_bytes()); + texture_params_bytes[36..40].copy_from_slice(&left.to_le_bytes()); + texture_params_bytes[40..44].copy_from_slice(&width.to_le_bytes()); + texture_params_bytes[44..48].copy_from_slice(&height.to_le_bytes()); + texture_params_bytes[48..52].copy_from_slice(&crop.top.to_le_bytes()); + texture_params_bytes[52..56].copy_from_slice(&crop.left.to_le_bytes()); + texture_params_bytes[56..60].copy_from_slice(&crop.width.to_le_bytes()); + texture_params_bytes[60..64].copy_from_slice(&crop.height.to_le_bytes()); + texture_params_bytes[64..68].copy_from_slice(&rotation_degrees.to_le_bytes()); + texture_params_bytes[68..72].copy_from_slice(&border_width.to_le_bytes()); + texture_params.push(texture_params_bytes); + layout_infos.push(layout_info); + } + super::RenderLayoutContent::BoxShadow { color, blur_radius } => { + let layout_info = LayoutInfo { + layout_type: 2, + index: box_shadow_params.len() as u32, + masks_len: masks.len() as u32, + }; + let mut box_shadow_params_bytes = [0u8; 64]; + box_shadow_params_bytes[0..16].copy_from_slice(&border_radius_bytes); + box_shadow_params_bytes[16..32].copy_from_slice(&color_to_bytes(*color)); + box_shadow_params_bytes[32..36].copy_from_slice(&top.to_le_bytes()); + box_shadow_params_bytes[36..40].copy_from_slice(&left.to_le_bytes()); + box_shadow_params_bytes[40..44].copy_from_slice(&width.to_le_bytes()); + box_shadow_params_bytes[44..48].copy_from_slice(&height.to_le_bytes()); + box_shadow_params_bytes[48..52] + .copy_from_slice(&rotation_degrees.to_le_bytes()); + box_shadow_params_bytes[52..56].copy_from_slice(&blur_radius.to_le_bytes()); + box_shadow_params.push(box_shadow_params_bytes); + layout_infos.push(layout_info); + } + } + if masks.len() > MAX_MASKS { + error!( + "Max parent border radiuses count ({}) exceeded ({}). Skipping rendering some og them.", + MAX_MASKS, + masks.len() + ); + } + + let mut masks_bytes = Vec::new(); + + for mask in masks.iter().take(20) { + let mut mask_bytes = [0u8; 32]; + mask_bytes[0..16].copy_from_slice(&borders_radius_to_bytes(mask.radius)); + mask_bytes[16..20].copy_from_slice(&mask.top.to_le_bytes()); + mask_bytes[20..24].copy_from_slice(&mask.left.to_le_bytes()); + mask_bytes[24..28].copy_from_slice(&mask.width.to_le_bytes()); + mask_bytes[28..32].copy_from_slice(&mask.height.to_le_bytes()); + + masks_bytes.push(mask_bytes); + } + + masks_bytes.resize_with(20, || [0u8; 32]); + match self.bind_groups_2.get(index) { + Some((_bg, buffer)) => { + ctx.queue.write_buffer(buffer, 0, &masks_bytes.concat()); + } + None => { + error!("Not enought parent border radiuses bind groups preallocated"); + } + } + + ctx.queue + .write_buffer(&self.bind_groups_2[index].1, 0, &masks_bytes.concat()); } - } + texture_params.resize_with(100, || [0u8; 80]); + color_params.resize_with(100, || [0u8; 80]); + box_shadow_params.resize_with(100, || [0u8; 64]); + + ctx.queue + .write_buffer(&self.texture_params_buffer, 0, &texture_params.concat()); + ctx.queue + .write_buffer(&self.color_params_buffer, 0, &color_params.concat()); + ctx.queue.write_buffer( + &self.box_shadow_params_buffer, + 0, + &box_shadow_params.concat(), + ); - fn shader_buffer_content(params: &[LayoutNodeParams]) -> bytes::Bytes { - // this should only be enabled on `wasm32`, but it needs to be enabled as a temporary fix - // (@wbarczynski has a PR fixing this in the works right now) - let params = { - // On WebGL we have to fill the whole array - const MAX_PARAMS_COUNT: usize = 100; - let mut params = params.to_vec(); - params.resize_with(MAX_PARAMS_COUNT, LayoutNodeParams::default); - params - }; - - params - .iter() - .map(LayoutNodeParams::shader_buffer_content) - .collect::>() - .concat() - .into() + layout_infos } } -impl LayoutNodeParams { - fn shader_buffer_content(&self) -> [u8; 160] { - let Self { - transform_vertices_matrix, - transform_texture_coords_matrix, - is_texture, - background_color, - } = self; - let mut result = [0; 160]; - fn from_u8_color(value: u8) -> [u8; 4] { - (value as f32 / 255.0).to_ne_bytes() - } +fn create_buffer(ctx: &WgpuCtx, size: usize) -> wgpu::Buffer { + ctx.device.create_buffer_init(&BufferInitDescriptor { + label: Some("params buffer"), + contents: &vec![0u8; size], + usage: BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + }) +} - result[0..64].copy_from_slice(bytemuck::bytes_of(&transform_vertices_matrix.transpose())); - result[64..128].copy_from_slice(bytemuck::bytes_of( - &transform_texture_coords_matrix.transpose(), - )); - result[128..132].copy_from_slice(&from_u8_color(background_color.0)); - result[132..136].copy_from_slice(&from_u8_color(background_color.1)); - result[136..140].copy_from_slice(&from_u8_color(background_color.2)); - result[140..144].copy_from_slice(&from_u8_color(background_color.3)); +fn borders_radius_to_bytes(border_radius: BorderRadius) -> [u8; 16] { + let mut result = [0u8; 16]; + result[0..4].copy_from_slice(&border_radius.top_left.to_le_bytes()); + result[4..8].copy_from_slice(&border_radius.top_right.to_le_bytes()); + result[8..12].copy_from_slice(&border_radius.bottom_right.to_le_bytes()); + result[12..16].copy_from_slice(&border_radius.bottom_left.to_le_bytes()); + result +} - result[144..148].copy_from_slice(&is_texture.to_ne_bytes()); - // 12 bytes padding +fn color_to_bytes(color: RGBAColor) -> [u8; 16] { + let RGBAColor(r, g, b, a) = color; + let mut result = [0u8; 16]; + result[0..4].copy_from_slice(&srgb_to_linear(r).to_le_bytes()); + result[4..8].copy_from_slice(&srgb_to_linear(g).to_le_bytes()); + result[8..12].copy_from_slice(&srgb_to_linear(b).to_le_bytes()); + result[12..16].copy_from_slice(&(a as f32 / 255.0).to_le_bytes()); + result +} - result +fn srgb_to_linear(color: u8) -> f32 { + let color = color as f32 / 255.0; + if color < 0.04045 { + color / 12.92 + } else { + f32::powf((color + 0.055) / 1.055, 2.4) } } diff --git a/compositor_render/src/transformations/layout/shader.rs b/compositor_render/src/transformations/layout/shader.rs index 12fcc6243..55cbd00a6 100644 --- a/compositor_render/src/transformations/layout/shader.rs +++ b/compositor_render/src/transformations/layout/shader.rs @@ -1,16 +1,24 @@ use std::sync::Arc; -use crate::wgpu::{ - common_pipeline::{self, CreateShaderError, Sampler}, - texture::{NodeTexture, NodeTextureState}, - WgpuCtx, WgpuErrorScope, +use tracing::error; + +use crate::{ + wgpu::{ + common_pipeline::{self, CreateShaderError, Sampler}, + texture::{NodeTexture, NodeTextureState}, + WgpuCtx, WgpuErrorScope, + }, + Resolution, }; +use super::{params::ParamsBindGroups, RenderLayout}; + #[derive(Debug)] pub struct LayoutShader { pipeline: wgpu::RenderPipeline, sampler: Sampler, texture_bgl: wgpu::BindGroupLayout, + params_bind_groups: ParamsBindGroups, } impl LayoutShader { @@ -32,8 +40,8 @@ impl LayoutShader { shader_module: wgpu::ShaderModule, ) -> Result { let sampler = Sampler::new(&wgpu_ctx.device); - let texture_bgl = common_pipeline::create_single_texture_bgl(&wgpu_ctx.device); + let params_bind_groups = ParamsBindGroups::new(wgpu_ctx); let pipeline_layout = wgpu_ctx @@ -42,12 +50,13 @@ impl LayoutShader { label: Some("shader transformation pipeline layout"), bind_group_layouts: &[ &texture_bgl, - &wgpu_ctx.uniform_bgl, + ¶ms_bind_groups.bind_group_1_layout, + ¶ms_bind_groups.bind_group_2_layout, &sampler.bind_group_layout, ], push_constant_ranges: &[wgpu::PushConstantRange { stages: wgpu::ShaderStages::VERTEX_FRAGMENT, - range: 0..4, + range: 0..16, }], }); @@ -61,18 +70,31 @@ impl LayoutShader { pipeline, sampler, texture_bgl, + params_bind_groups, }) } pub fn render( &self, wgpu_ctx: &Arc, - params: &wgpu::BindGroup, + output_resolution: Resolution, + layouts: Vec, textures: &[Option<&NodeTexture>], target: &NodeTextureState, ) { + let layout_infos = self + .params_bind_groups + .update(wgpu_ctx, output_resolution, layouts); let input_texture_bgs: Vec = self.input_textures_bg(wgpu_ctx, textures); + if layout_infos.len() != input_texture_bgs.len() { + error!( + "Layout infos len ({:?}) and textures bind groups count ({:?}) mismatch", + layout_infos.len(), + input_texture_bgs.len() + ); + } + let mut encoder = wgpu_ctx.device.create_command_encoder(&Default::default()); { let mut render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { @@ -91,18 +113,24 @@ impl LayoutShader { occlusion_query_set: None, }); - for (layout_id, texture_bg) in input_texture_bgs.iter().enumerate() { + for (index, (texture_bg, layout_info)) in input_texture_bgs + .iter() + .zip(layout_infos.iter()) + .take(100) + .enumerate() + { render_pass.set_pipeline(&self.pipeline); render_pass.set_push_constants( wgpu::ShaderStages::VERTEX_FRAGMENT, 0, - &(layout_id as u32).to_le_bytes(), + &layout_info.to_bytes(), ); render_pass.set_bind_group(0, texture_bg, &[]); - render_pass.set_bind_group(1, params, &[]); - render_pass.set_bind_group(2, &self.sampler.bind_group, &[]); + render_pass.set_bind_group(1, &self.params_bind_groups.bind_group_1, &[]); + render_pass.set_bind_group(2, &self.params_bind_groups.bind_groups_2[index].0, &[]); + render_pass.set_bind_group(3, &self.sampler.bind_group, &[]); wgpu_ctx.plane.draw(&mut render_pass); } diff --git a/compositor_render/src/transformations/text_renderer.rs b/compositor_render/src/transformations/text_renderer.rs index e4f9353a2..4d5efd959 100644 --- a/compositor_render/src/transformations/text_renderer.rs +++ b/compositor_render/src/transformations/text_renderer.rs @@ -74,6 +74,24 @@ impl TextRendererNode { return; } + if self.resolution.width == 0 || self.resolution.height == 0 { + // We can't use zero-sized textures + let target_state = target.ensure_size( + renderer_ctx.wgpu_ctx, + Resolution { + width: 1, + height: 1, + }, + ); + + target_state + .rgba_texture() + .upload(renderer_ctx.wgpu_ctx, &[0; 4]); + + self.was_rendered = true; + return; + } + let text_renderer = renderer_ctx.text_renderer_ctx; let font_system = &mut text_renderer.font_system.lock().unwrap(); let swash_cache = &mut text_renderer.swash_cache.lock().unwrap(); @@ -82,7 +100,7 @@ impl TextRendererNode { let mut viewport = glyphon::Viewport::new(&renderer_ctx.wgpu_ctx.device, cache); viewport.update(&renderer_ctx.wgpu_ctx.queue, self.resolution.into()); - let swapchain_format = TextureFormat::Rgba8Unorm; + let swapchain_format = TextureFormat::Rgba8UnormSrgb; let mut atlas = TextAtlas::new( &renderer_ctx.wgpu_ctx.device, &renderer_ctx.wgpu_ctx.queue, @@ -246,6 +264,11 @@ impl TextRendererCtx { .load_font_source(Source::Binary(Arc::new(include_bytes!( "../../fonts/Inter_18pt-Italic.ttf" )))); + font_system + .db_mut() + .load_font_source(Source::Binary(Arc::new(include_bytes!( + "../../fonts/Inter_18pt-Bold.ttf" + )))); Self { font_system: Mutex::new(font_system), swash_cache: Mutex::new(SwashCache::new()), diff --git a/compositor_render/src/transformations/web_renderer.rs b/compositor_render/src/transformations/web_renderer.rs index bd6fbc918..7f306a7c5 100644 --- a/compositor_render/src/transformations/web_renderer.rs +++ b/compositor_render/src/transformations/web_renderer.rs @@ -10,6 +10,8 @@ mod renderer; #[path = "web_renderer/disabled_renderer.rs"] mod renderer; +mod tranformation_matrices; + pub use renderer::*; pub mod chromium_context; diff --git a/compositor_render/src/transformations/web_renderer/browser_client.rs b/compositor_render/src/transformations/web_renderer/browser_client.rs index 52a707bd9..491f16491 100644 --- a/compositor_render/src/transformations/web_renderer/browser_client.rs +++ b/compositor_render/src/transformations/web_renderer/browser_client.rs @@ -1,16 +1,16 @@ use std::sync::{Arc, Mutex}; -use crate::{ - transformations::layout::{vertices_transformation_matrix, Position}, - Resolution, -}; +use crate::Resolution; use bytes::Bytes; use compositor_chromium::cef; use log::error; use crate::transformations::web_renderer::{FrameData, SourceTransforms}; -use super::GET_FRAME_POSITIONS_MESSAGE; +use super::{ + tranformation_matrices::{vertices_transformation_matrix, Position}, + GET_FRAME_POSITIONS_MESSAGE, +}; #[derive(Clone)] pub(super) struct BrowserClient { diff --git a/compositor_render/src/transformations/layout/transformation_matrices.rs b/compositor_render/src/transformations/web_renderer/tranformation_matrices.rs similarity index 54% rename from compositor_render/src/transformations/layout/transformation_matrices.rs rename to compositor_render/src/transformations/web_renderer/tranformation_matrices.rs index 0c1c26767..4168f1ed9 100644 --- a/compositor_render/src/transformations/layout/transformation_matrices.rs +++ b/compositor_render/src/transformations/web_renderer/tranformation_matrices.rs @@ -2,57 +2,8 @@ use nalgebra_glm::{rotate_z, scale, translate, vec3, Mat4, Vec3}; use crate::Resolution; -use super::RenderLayout; - -impl RenderLayout { - /// Returns matrix that transforms input plane vertices - /// (located in corners of clip space), to final position - pub(super) fn vertices_transformation_matrix(&self, output_resolution: &Resolution) -> Mat4 { - vertices_transformation_matrix( - &Position { - top: self.top, - left: self.left, - width: self.width, - height: self.height, - rotation_degrees: self.rotation_degrees, - }, - output_resolution, - ) - } - - pub(super) fn texture_coords_transformation_matrix( - &self, - input_resolution: &Option, - ) -> Mat4 { - let Some(input_resolution) = input_resolution else { - return Mat4::identity(); - }; - - match self.content { - super::RenderLayoutContent::Color(_) => Mat4::identity(), - super::RenderLayoutContent::ChildNode { ref crop, .. } => { - let x_scale = crop.width / input_resolution.width as f32; - let y_scale = crop.height / input_resolution.height as f32; - - let x_translate = crop.left / input_resolution.width as f32; - let y_translate = crop.top / input_resolution.height as f32; - - let mut transform_texture_matrix = Mat4::identity(); - transform_texture_matrix = translate( - &transform_texture_matrix, - &vec3(x_translate, y_translate, 0.0), - ); - transform_texture_matrix = - scale(&transform_texture_matrix, &vec3(x_scale, y_scale, 1.0)); - - transform_texture_matrix - } - } - } -} - #[derive(Debug)] -pub(crate) struct Position { +pub(super) struct Position { pub(crate) top: f32, pub(crate) left: f32, pub(crate) width: f32, @@ -60,7 +11,7 @@ pub(crate) struct Position { pub(crate) rotation_degrees: f32, } -pub(crate) fn vertices_transformation_matrix( +pub(super) fn vertices_transformation_matrix( position: &Position, output_resolution: &Resolution, ) -> Mat4 { diff --git a/compositor_render/src/wgpu.rs b/compositor_render/src/wgpu.rs index ff9921a65..e3e7196da 100644 --- a/compositor_render/src/wgpu.rs +++ b/compositor_render/src/wgpu.rs @@ -7,7 +7,7 @@ pub(crate) mod texture; pub(crate) mod utils; pub(crate) use ctx::WgpuCtx; -pub use ctx::{create_wgpu_ctx, required_wgpu_features, set_required_wgpu_limits}; +pub use ctx::{create_wgpu_ctx, required_wgpu_features, set_required_wgpu_limits, WgpuComponents}; pub use wgpu::Features as WgpuFeatures; #[must_use] diff --git a/compositor_render/src/wgpu/common_pipeline.rs b/compositor_render/src/wgpu/common_pipeline.rs index bf373deeb..5c22de2cd 100644 --- a/compositor_render/src/wgpu/common_pipeline.rs +++ b/compositor_render/src/wgpu/common_pipeline.rs @@ -118,7 +118,7 @@ pub fn create_render_pipeline( module: shader_module, entry_point: crate::wgpu::common_pipeline::FRAGMENT_ENTRYPOINT_NAME, targets: &[Some(wgpu::ColorTargetState { - format: wgpu::TextureFormat::Rgba8Unorm, + format: wgpu::TextureFormat::Rgba8UnormSrgb, write_mask: wgpu::ColorWrites::all(), blend: Some(wgpu::BlendState::ALPHA_BLENDING), })], diff --git a/compositor_render/src/wgpu/ctx.rs b/compositor_render/src/wgpu/ctx.rs index 4bf23706f..96aab0f06 100644 --- a/compositor_render/src/wgpu/ctx.rs +++ b/compositor_render/src/wgpu/ctx.rs @@ -34,7 +34,8 @@ impl WgpuCtx { Self::new_from_device_queue(device, queue)? } None => { - let (device, queue) = create_wgpu_ctx(force_gpu, features, Default::default())?; + let WgpuComponents { device, queue, .. } = + create_wgpu_ctx(force_gpu, features, Default::default(), None)?; Self::new_from_device_queue(device, queue)? } }; @@ -101,11 +102,20 @@ pub fn set_required_wgpu_limits(limits: wgpu::Limits) -> wgpu::Limits { } } +#[derive(Clone)] +pub struct WgpuComponents { + pub device: Arc, + pub queue: Arc, + pub adapter: Arc, + pub instance: Arc, +} + pub fn create_wgpu_ctx( force_gpu: bool, features: wgpu::Features, limits: wgpu::Limits, -) -> Result<(Arc, Arc), CreateWgpuCtxError> { + compatible_surface: Option<&wgpu::Surface<'_>>, +) -> Result { let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: wgpu::Backends::all(), ..Default::default() @@ -117,7 +127,7 @@ pub fn create_wgpu_ctx( let adapter = pollster::block_on(instance.request_adapter(&wgpu::RequestAdapterOptionsBase { power_preference: wgpu::PowerPreference::HighPerformance, force_fallback_adapter: false, - compatible_surface: None, + compatible_surface, })) .ok_or(CreateWgpuCtxError::NoAdapter)?; @@ -148,7 +158,12 @@ pub fn create_wgpu_ctx( }, None, ))?; - Ok((device.into(), queue.into())) + Ok(WgpuComponents { + instance: instance.into(), + adapter: adapter.into(), + device: device.into(), + queue: queue.into(), + }) } fn uniform_bind_group_layout(device: &wgpu::Device) -> wgpu::BindGroupLayout { diff --git a/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.rs b/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.rs index 821ad2fa7..5b7e9b909 100644 --- a/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.rs +++ b/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.rs @@ -42,7 +42,7 @@ impl InterleavedYuv422ToRgbaConverter { module: &shader_module, entry_point: "fs_main", targets: &[Some(wgpu::ColorTargetState { - format: wgpu::TextureFormat::Rgba8Unorm, + format: wgpu::TextureFormat::Rgba8UnormSrgb, write_mask: wgpu::ColorWrites::all(), blend: None, })], diff --git a/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.wgsl b/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.wgsl index 232e0ccc3..55dc34de0 100644 --- a/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.wgsl +++ b/compositor_render/src/wgpu/format/interleaved_yuv_to_rgba.wgsl @@ -21,6 +21,14 @@ fn vs_main(input: VertexInput) -> VertexOutput { @group(0) @binding(0) var texture: texture_2d; @group(1) @binding(0) var sampler_: sampler; +fn srgb_to_linear(srgb: vec3) -> vec3 { + let cutoff = step(srgb, vec3(0.04045)); + let higher = pow((srgb + vec3(0.055))/vec3(1.055), vec3(2.4)); + let lower = srgb/vec3(12.92); + + return mix(higher, lower, cutoff); +} + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { var dimensions = textureDimensions(texture); @@ -48,5 +56,6 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4 { let g = y - 0.34414 * (u - 128.0 / 255.0) - 0.71414 * (v - 128.0 / 255.0); let b = y + 1.77200 * (u - 128.0 / 255.0); - return vec4(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0), 1.0); + let srgb = vec3(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0)); + return vec4(srgb_to_linear(srgb), 1.0); } diff --git a/compositor_render/src/wgpu/format/nv12_to_rgba.rs b/compositor_render/src/wgpu/format/nv12_to_rgba.rs index ea8686c7b..dddcb5091 100644 --- a/compositor_render/src/wgpu/format/nv12_to_rgba.rs +++ b/compositor_render/src/wgpu/format/nv12_to_rgba.rs @@ -41,7 +41,7 @@ impl Nv12ToRgbaConverter { module: &shader_module, entry_point: "fs_main", targets: &[Some(wgpu::ColorTargetState { - format: wgpu::TextureFormat::Rgba8Unorm, + format: wgpu::TextureFormat::Rgba8UnormSrgb, write_mask: wgpu::ColorWrites::all(), blend: None, })], diff --git a/compositor_render/src/wgpu/format/nv12_to_rgba.wgsl b/compositor_render/src/wgpu/format/nv12_to_rgba.wgsl index 17173d020..5883784b0 100644 --- a/compositor_render/src/wgpu/format/nv12_to_rgba.wgsl +++ b/compositor_render/src/wgpu/format/nv12_to_rgba.wgsl @@ -23,6 +23,14 @@ fn vs_main(input: VertexInput) -> VertexOutput { @group(1) @binding(0) var sampler_: sampler; +fn srgb_to_linear(srgb: vec3) -> vec3 { + let cutoff = step(srgb, vec3(0.04045)); + let higher = pow((srgb + vec3(0.055))/vec3(1.055), vec3(2.4)); + let lower = srgb/vec3(12.92); + + return mix(higher, lower, cutoff); +} + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { var y = textureSample(y_texture, sampler_, input.tex_coords).x; @@ -34,5 +42,6 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4 { let g = y - 0.34414 * (u - 128.0 / 255.0) - 0.71414 * (v - 128.0 / 255.0); let b = y + 1.77200 * (u - 128.0 / 255.0); - return vec4(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0), 1.0); + let srgb = vec3(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0)); + return vec4(srgb_to_linear(srgb), 1.0); } diff --git a/compositor_render/src/wgpu/format/planar_yuv_to_rgba.rs b/compositor_render/src/wgpu/format/planar_yuv_to_rgba.rs index 6eb070f2d..79fed53a8 100644 --- a/compositor_render/src/wgpu/format/planar_yuv_to_rgba.rs +++ b/compositor_render/src/wgpu/format/planar_yuv_to_rgba.rs @@ -47,7 +47,7 @@ impl PlanarYuvToRgbaConverter { module: &shader_module, entry_point: "fs_main", targets: &[Some(wgpu::ColorTargetState { - format: wgpu::TextureFormat::Rgba8Unorm, + format: wgpu::TextureFormat::Rgba8UnormSrgb, write_mask: wgpu::ColorWrites::all(), blend: None, })], diff --git a/compositor_render/src/wgpu/format/planar_yuv_to_rgba.wgsl b/compositor_render/src/wgpu/format/planar_yuv_to_rgba.wgsl index 3b774312b..588f02cd1 100644 --- a/compositor_render/src/wgpu/format/planar_yuv_to_rgba.wgsl +++ b/compositor_render/src/wgpu/format/planar_yuv_to_rgba.wgsl @@ -32,6 +32,14 @@ struct PushConstantParams { var params: PushConstantParams; +fn srgb_to_linear(srgb: vec3) -> vec3 { + let cutoff = step(srgb, vec3(0.04045)); + let higher = pow((srgb + vec3(0.055))/vec3(1.055), vec3(2.4)); + let lower = srgb/vec3(12.92); + + return mix(higher, lower, cutoff); +} + @fragment fn fs_main(input: VertexOutput) -> @location(0) vec4 { var y = textureSample(y_texture, sampler_, input.tex_coords).x; @@ -50,5 +58,6 @@ fn fs_main(input: VertexOutput) -> @location(0) vec4 { let g = y - 0.34414 * (u - 128.0 / 255.0) - 0.71414 * (v - 128.0 / 255.0); let b = y + 1.77200 * (u - 128.0 / 255.0); - return vec4(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0), 1.0); + let srgb = vec3(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0)); + return vec4(srgb_to_linear(srgb), 1.0); } diff --git a/compositor_render/src/wgpu/format/rgba_to_yuv.wgsl b/compositor_render/src/wgpu/format/rgba_to_yuv.wgsl index 126eb1987..7fe4ff104 100644 --- a/compositor_render/src/wgpu/format/rgba_to_yuv.wgsl +++ b/compositor_render/src/wgpu/format/rgba_to_yuv.wgsl @@ -23,26 +23,35 @@ fn vs_main(input: VertexInput) -> VertexOutput { var plane_selector: u32; +fn linear_to_srgb(linear: vec3) -> vec3 { + let cutoff = step(linear, vec3(0.0031308)); + let higher = vec3(1.055)*pow(linear, vec3(1.0/2.4)) - vec3(0.055); + let lower = linear * vec3(12.92); + + return mix(higher, lower, cutoff); +} + @fragment fn fs_main(input: VertexOutput) -> @location(0) f32 { - let color = textureSample(texture, sampler_, input.tex_coords); - var conversion_weights: vec4; + let linear = textureSample(texture, sampler_, input.tex_coords); + let color = linear_to_srgb(linear.rgb); + var conversion_weights: vec3; var conversion_bias: f32; if(plane_selector == 0u) { // Y - conversion_weights = vec4(0.299, 0.587, 0.114, 0.0); + conversion_weights = vec3(0.299, 0.587, 0.114); conversion_bias = 0.0; } else if(plane_selector == 1u) { // U - conversion_weights = vec4(-0.168736, -0.331264, 0.5, 0.0); + conversion_weights = vec3(-0.168736, -0.331264, 0.5); conversion_bias = 128.0 / 255.0; } else if(plane_selector == 2u) { // V - conversion_weights = vec4(0.5, -0.418688, -0.081312, 0.0); + conversion_weights = vec3(0.5, -0.418688, -0.081312); conversion_bias = 128.0 / 255.0; } else { - conversion_weights = vec4(); + conversion_weights = vec3(); } return clamp(dot(color, conversion_weights) + conversion_bias, 0.0, 1.0); diff --git a/compositor_render/src/wgpu/texture/base.rs b/compositor_render/src/wgpu/texture/base.rs index 8cb6e415b..edd9f3f2e 100644 --- a/compositor_render/src/wgpu/texture/base.rs +++ b/compositor_render/src/wgpu/texture/base.rs @@ -94,7 +94,7 @@ impl Texture { height: 1, depth_or_array_layers: 1, }, - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rgba8UnormSrgb, wgpu::TextureUsages::TEXTURE_BINDING, ) } diff --git a/compositor_render/src/wgpu/texture/bgra.rs b/compositor_render/src/wgpu/texture/bgra.rs index 00ed62648..99c444375 100644 --- a/compositor_render/src/wgpu/texture/bgra.rs +++ b/compositor_render/src/wgpu/texture/bgra.rs @@ -15,7 +15,7 @@ impl BGRATexture { height: resolution.height as u32, depth_or_array_layers: 1, }, - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rgba8UnormSrgb, wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::TEXTURE_BINDING, )) } diff --git a/compositor_render/src/wgpu/texture/interleaved_yuv422.rs b/compositor_render/src/wgpu/texture/interleaved_yuv422.rs index f9631aa2e..f6956222d 100644 --- a/compositor_render/src/wgpu/texture/interleaved_yuv422.rs +++ b/compositor_render/src/wgpu/texture/interleaved_yuv422.rs @@ -27,7 +27,7 @@ impl InterleavedYuv422Texture { // g - y1 // b - v // a - y2 - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rgba8UnormSrgb, wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC diff --git a/compositor_render/src/wgpu/texture/rgba.rs b/compositor_render/src/wgpu/texture/rgba.rs index 26b399d22..e7c146253 100644 --- a/compositor_render/src/wgpu/texture/rgba.rs +++ b/compositor_render/src/wgpu/texture/rgba.rs @@ -18,7 +18,7 @@ impl RGBATexture { height: resolution.height as u32, depth_or_array_layers: 1, }, - wgpu::TextureFormat::Rgba8Unorm, + wgpu::TextureFormat::Rgba8UnormSrgb, wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC diff --git a/compositor_web/Cargo.toml b/compositor_web/Cargo.toml index 9c39d284e..682029a67 100644 --- a/compositor_web/Cargo.toml +++ b/compositor_web/Cargo.toml @@ -17,7 +17,7 @@ tracing-subscriber = "0.2.19" log = { workspace = true } wasm-log = "0.3.1" js-sys = "0.3.69" -wasm-bindgen = "0.2.92" +wasm-bindgen = "0.2.93" wasm-bindgen-futures = "0.4.42" web-sys = { version = "0.3.69", features = [ "Document", @@ -36,3 +36,6 @@ glyphon = { workspace = true } [target.'cfg(target_arch = "wasm32")'.dependencies] getrandom = { version = "0.2", features = ["js"] } + +[package.metadata.wasm-pack.profile.release] +wasm-opt = true diff --git a/compositor_web/src/wasm/input_uploader.rs b/compositor_web/src/wasm/input_uploader.rs index dec959680..66aa5df6a 100644 --- a/compositor_web/src/wasm/input_uploader.rs +++ b/compositor_web/src/wasm/input_uploader.rs @@ -97,8 +97,8 @@ impl InputUploader { mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, - view_formats: &[wgpu::TextureFormat::Rgba8Unorm], + format: wgpu::TextureFormat::Rgba8UnormSrgb, + view_formats: &[wgpu::TextureFormat::Rgba8UnormSrgb], usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC diff --git a/demos/.eslintrc.json b/demos/.eslintrc.json deleted file mode 100644 index fc0d40cca..000000000 --- a/demos/.eslintrc.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "env": { - "node": true - }, - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "prettier" - ], - "plugins": [ - "prettier" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": [ - "tsconfig.json" - ] - }, - "rules": { - "prettier/prettier": ["error"], - "@typescript-eslint/no-explicit-any": [0, {}], - "@typescript-eslint/no-floating-promises": "error", - "no-constant-condition": [0] - } -} diff --git a/demos/.prettierrc b/demos/.prettierrc deleted file mode 100644 index 58660ea94..000000000 --- a/demos/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "printWidth": 100, - "tabWidth": 2, - "singleQuote": true, - "bracketSameLine": true, - "trailingComma": "es5", - "arrowParens": "avoid", - "endOfLine": "auto" -} diff --git a/demos/.prettierrc.js b/demos/.prettierrc.js new file mode 100644 index 000000000..74da53f68 --- /dev/null +++ b/demos/.prettierrc.js @@ -0,0 +1,9 @@ +export default { + printWidth: 100, + tabWidth: 2, + singleQuote: true, + bracketSameLine: true, + trailingComma: 'es5', + arrowParens: 'avoid', + endOfLine: 'auto', +}; diff --git a/demos/1-videoconferencing/index.tsx b/demos/1-videoconferencing/index.tsx index cdbbeddb9..ef9e480e4 100644 --- a/demos/1-videoconferencing/index.tsx +++ b/demos/1-videoconferencing/index.tsx @@ -34,6 +34,7 @@ function App() { }, 2000); return () => clearTimeout(timeout); }, [counter]); + return ; } diff --git a/demos/2-tv_broadcast/index.tsx b/demos/2-tv_broadcast/index.tsx index c01b50277..12f081d3f 100644 --- a/demos/2-tv_broadcast/index.tsx +++ b/demos/2-tv_broadcast/index.tsx @@ -2,16 +2,8 @@ import { ffmpegSendVideoFromMp4 } from '../utils/ffmpeg'; import { downloadAsync } from '../utils/utils'; import fs from 'fs-extra'; import path from 'path'; -import { - View, - Image, - Text, - Rescaler, - Shader, - InputStream, - Transition, - useInputStreams, -} from 'live-compositor'; +import type { Transition } from 'live-compositor'; +import { View, Image, Text, Rescaler, Shader, InputStream, useInputStreams } from 'live-compositor'; import LiveCompositor from '@live-compositor/node'; import { useEffect, useState } from 'react'; import { gstStartPlayer } from '../utils/gst'; diff --git a/demos/eslint.config.js b/demos/eslint.config.js new file mode 100644 index 000000000..17af4d26d --- /dev/null +++ b/demos/eslint.config.js @@ -0,0 +1,86 @@ +import globals from 'globals'; + +import eslintRecommended from '@eslint/js'; +import eslintConfigPrettier from 'eslint-config-prettier'; + +import pluginImport from 'eslint-plugin-import'; +import pluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; +import { plugin as tsEslintPlugin } from 'typescript-eslint'; +import reactHooks from 'eslint-plugin-react-hooks'; +import tsParser from '@typescript-eslint/parser'; + +export default [ + eslintRecommended.configs.recommended, + pluginImport.flatConfigs.recommended, + pluginPrettierRecommended, + eslintConfigPrettier, + { + files: ['**/*.{js,jsx,ts,tsx}'], + ignores: ['.prettierrc.js'], + plugins: { + '@typescript-eslint': tsEslintPlugin, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + project: 'tsconfig.json', + }, + ecmaVersion: 'latest', + sourceType: 'module', + globals: { + ...globals.browser, + ...globals.node, + }, + }, + settings: { + 'import/parsers': { + '@typescript-eslint/parser': ['.ts', '.tsx'], + }, + 'import/resolver': { + typescript: { + alwaysTryTypes: true, + project: 'tsconfig.json', + }, + }, + }, + rules: { + 'prettier/prettier': ['error'], + 'import/no-unresolved': 'error', + '@typescript-eslint/no-explicit-any': [0, {}], + '@typescript-eslint/no-floating-promises': ['error'], + 'no-constant-condition': [0], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + vars: 'local', + }, + ], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + }, + ], + }, + }, + { + files: ['**/*.{ts,tsx}'], + plugins: { + 'react-hooks': reactHooks, + }, + rules: { + ...reactHooks.configs.recommended.rules, + }, + }, + { + ignores: ['eslint.config.js', '**/generated/**/*', '**/*.d.ts'], + }, +]; diff --git a/demos/package-lock.json b/demos/package-lock.json deleted file mode 100644 index 231b5975f..000000000 --- a/demos/package-lock.json +++ /dev/null @@ -1,4383 +0,0 @@ -{ - "name": "live_compositor_demos", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "live_compositor_demos", - "version": "1.0.0", - "license": "BUSL-1.1", - "dependencies": { - "@live-compositor/node": "^0.1.0", - "@types/fs-extra": "^11.0.2", - "@types/node": "^20.12.11", - "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.7.3", - "@typescript-eslint/parser": "^6.7.3", - "chalk": "^4.1.2", - "eslint": "^8.50.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-prettier": "^5.0.0", - "fs-extra": "^11.1.1", - "json-schema-to-typescript": "^14.0.4", - "live-compositor": "^0.1.0", - "node-fetch": "^2.7.0", - "node-popup": "^0.1.14", - "prettier": "^3.0.3", - "react": "^18.3.1", - "ts-node": "^10.9.1", - "typescript": "^5.2.2" - }, - "devDependencies": { - "@types/react": "^18.3.9" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.6.1", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.6.1.tgz", - "integrity": "sha512-DxjgKBCoyReu4p5HMvpmgSOfRhhBcuf5V5soDDRgOTZMwsA4KSFzol1abFZgiCTE11L2kKGca5Md9GwDdXVBwQ==", - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==" - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/fs-minipass": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", - "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", - "dependencies": { - "minipass": "^7.0.4" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==" - }, - "node_modules/@live-compositor/core": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@live-compositor/core/-/core-0.1.0.tgz", - "integrity": "sha512-0ZqPH3kS1krO633j9930Wr/lBBNj6kdmwsEeOkmatgt9aApzcYTk6rxb2awdn4Oh5JcmDtVBf1zrLzgAT9iwcQ==", - "dependencies": { - "react-reconciler": "0.29.2" - }, - "peerDependencies": { - "live-compositor": "^0.1.0" - } - }, - "node_modules/@live-compositor/node": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@live-compositor/node/-/node-0.1.0.tgz", - "integrity": "sha512-Wdnq5cyWE2rEDy12IVue+98hsrigZtDnZlWrbDLPT29/ERCl2eSFeOSlnAaZvLqw26xmeNAVkjpBXqMjI1O3bg==", - "dependencies": { - "@live-compositor/core": "^0.1.0", - "fs-extra": "^11.2.0", - "node-fetch": "^2.6.7", - "tar": "^7.4.3", - "uuid": "^10.0.0", - "ws": "^8.18.0" - } - }, - "node_modules/@live-compositor/node/node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==" - }, - "node_modules/@types/fs-extra": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", - "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", - "dependencies": { - "@types/jsonfile": "*", - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==" - }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.1.tgz", - "integrity": "sha512-X+2qazGS3jxLAIz5JDXDzglAF3KpijdhFxlf/V1+hEsOUc+HnWi81L/uv/EvGuV90WY+7mPGFCUDGfQC3Gj95Q==" - }, - "node_modules/@types/node": { - "version": "20.12.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.11.tgz", - "integrity": "sha512-vDg9PZ/zi+Nqp6boSOT7plNuthRugEKixDv5sFTIpkE89MmNtEArAShI4mxuX2+UrLEe9pxC1vm2cjm9YlWbJw==", - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.3.9", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.9.tgz", - "integrity": "sha512-+BpAVyTpJkNWWSSnaLBk6ePpHLOGJKnEQNbINNovPWzvEUyAe3e+/d494QdEh71RekM/qV7lw6jzf1HGrJyAtQ==", - "dev": true, - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==" - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz", - "integrity": "sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==", - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/type-utils": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha", - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz", - "integrity": "sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag==", - "dependencies": { - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/utils": "6.21.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", - "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dependencies": { - "@typescript-eslint/types": "6.21.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^16.0.0 || >=18.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/agent-base": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz", - "integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==", - "dependencies": { - "es6-promisify": "^5.0.0" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==" - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/async-limiter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", - "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "engines": { - "node": "*" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/carlo": { - "version": "0.9.43", - "resolved": "https://registry.npmjs.org/carlo/-/carlo-0.9.43.tgz", - "integrity": "sha512-m3kCI4ZxYKCGmOoBNnu/Bq+FMZpfYV2P8qWuOcVa2HuxBgS5afG5Efw9D8v7IUhCc+4ox2Eag1BN9ERtGPr7Vg==", - "dependencies": { - "debug": "^4.1.0", - "puppeteer-core": "^1.9.0" - }, - "engines": { - "node": ">=7.6.0" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chownr": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", - "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", - "engines": { - "node": ">=18" - } - }, - "node_modules/cli-color": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-2.0.4.tgz", - "integrity": "sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.64", - "es6-iterator": "^2.0.3", - "memoizee": "^0.4.15", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "dev": true - }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-promise": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", - "integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==" - }, - "node_modules/es6-promisify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", - "integrity": "sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==", - "dependencies": { - "es6-promise": "^4.0.3" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", - "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.1.3.tgz", - "integrity": "sha512-C9GCVAs4Eq7ZC/XFQHITLiHJxQngdtraXaM+LoUFoFp/lHNl2Zn8f3WQbe9HvTBBQ9YnKFB0/2Ajdqwo5D1EAw==", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.8.6" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/extract-zip": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", - "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", - "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - } - }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==" - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", - "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/glob": { - "version": "10.3.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.15.tgz", - "integrity": "sha512-0c6RlJt1TICLyvJYIApxb8GsXoai0KUP7AxKKAtsYXdgJR1mGEUa7DgwShbdk1nly0PYoZj01xd4hzbq3fsjpw==", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^2.3.6", - "minimatch": "^9.0.1", - "minipass": "^7.0.4", - "path-scurry": "^1.11.0" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/https-proxy-agent": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", - "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", - "dependencies": { - "agent-base": "^4.3.0", - "debug": "^3.1.0" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/https-proxy-agent/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-promise": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", - "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "node_modules/jackspeak": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", - "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-schema-to-typescript": { - "version": "14.0.4", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-14.0.4.tgz", - "integrity": "sha512-covPOp3hrbD+oEcMvDxP5Rh6xNZj7lOTZkXAeQoDyu1PuEl1A6oRZ3Sy05HN11vXXmdJ6gLh5P3Qz0mgMPTzzw==", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.5", - "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.0", - "cli-color": "^2.0.4", - "glob": "^10.3.12", - "is-glob": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "mkdirp": "^3.0.1", - "mz": "^2.7.0", - "node-fetch": "^3.3.2", - "prettier": "^3.2.5" - }, - "bin": { - "json2ts": "dist/src/cli.js" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/json-schema-to-typescript/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/live-compositor": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/live-compositor/-/live-compositor-0.1.0.tgz", - "integrity": "sha512-TAScLUrHcSBAkAzQPsfyqvZ3EDHyETABKnp6E0uY7x1Zsqj+Xz4RkoOPB2cBJDORpSUkQUtj6pbchKUSXQ4Mnw==", - "peerDependencies": { - "react": "*" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", - "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/lru-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", - "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", - "dependencies": { - "es5-ext": "~0.10.2" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==" - }, - "node_modules/memoizee": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.15.tgz", - "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.53", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minizlib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", - "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "node_modules/minizlib/node_modules/rimraf": { - "version": "5.0.10", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", - "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/mkdirp": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", - "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/mz": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", - "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", - "dependencies": { - "any-promise": "^1.0.0", - "object-assign": "^4.0.1", - "thenify-all": "^1.0.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-popup": { - "version": "0.1.14", - "resolved": "https://registry.npmjs.org/node-popup/-/node-popup-0.1.14.tgz", - "integrity": "sha512-zmFaETuJn87rKY8Ib7IQVyBDcg9Uh7/GnPLFyPeCU1Tx5KA7Z2SBAs2kdhUBFiMElUzQwqllBRJoikpOf4ee2Q==", - "dependencies": { - "carlo": "0.9.43" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", - "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "engines": { - "node": ">=8" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "engines": { - "node": ">=6" - } - }, - "node_modules/puppeteer-core": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-1.20.0.tgz", - "integrity": "sha512-akoSCMDVv6BFd/4+dtW6mVgdaRQhy/cmkGzXcx9HAXZqnY9zXYbsfoXMiMpwt3+53U9zFGSjgvsi0mDKNJLfqg==", - "hasInstallScript": true, - "dependencies": { - "debug": "^4.1.0", - "extract-zip": "^1.6.6", - "https-proxy-agent": "^2.2.1", - "mime": "^2.0.3", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^2.6.1", - "ws": "^6.1.0" - }, - "engines": { - "node": ">=6.4.0" - } - }, - "node_modules/puppeteer-core/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/puppeteer-core/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/puppeteer-core/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/puppeteer-core/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-reconciler": { - "version": "0.29.2", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", - "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", - "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", - "dependencies": { - "call-bind": "^1.0.6", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-array-concat/node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==" - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", - "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "engines": { - "node": ">=8" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "engines": { - "node": ">=8" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.8.8.tgz", - "integrity": "sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/tar": { - "version": "7.4.3", - "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", - "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/thenify": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz", - "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==", - "dependencies": { - "any-promise": "^1.0.0" - } - }, - "node_modules/thenify-all": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", - "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==", - "dependencies": { - "thenify": ">= 3.1.0 < 4" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/timers-ext": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", - "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", - "dependencies": { - "es5-ext": "~0.10.46", - "next-tick": "1" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==" - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==" - }, - "node_modules/web-streams-polyfill": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", - "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/ws": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.3.tgz", - "integrity": "sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==", - "dependencies": { - "async-limiter": "~1.0.0" - } - }, - "node_modules/yallist": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", - "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", - "engines": { - "node": ">=18" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/demos/package.json b/demos/package.json index dcb838a5c..3d9bad87c 100644 --- a/demos/package.json +++ b/demos/package.json @@ -3,6 +3,7 @@ "version": "1.0.0", "description": "Demos for LiveCompositor - media server for low latency video and audio mixing/composing", "main": "index.js", + "type": "module", "scripts": { "lint": "eslint .", "typecheck": "tsc --noEmit", @@ -25,26 +26,30 @@ "dependencies": { "@live-compositor/node": "^0.1.0", "@types/fs-extra": "^11.0.2", - "@types/node": "^20.12.11", "@types/node-fetch": "^2.6.11", - "@typescript-eslint/eslint-plugin": "^6.7.3", - "@typescript-eslint/parser": "^6.7.3", "chalk": "^4.1.2", - "eslint": "^8.50.0", - "eslint-config-prettier": "^9.0.0", - "eslint-plugin-import": "^2.28.1", - "eslint-plugin-prettier": "^5.0.0", "fs-extra": "^11.1.1", "json-schema-to-typescript": "^14.0.4", "live-compositor": "^0.1.0", "node-fetch": "^2.7.0", "node-popup": "^0.1.14", - "prettier": "^3.0.3", - "react": "^18.3.1", - "ts-node": "^10.9.1", - "typescript": "^5.2.2" + "react": "^18.3.1" }, "devDependencies": { - "@types/react": "^18.3.9" + "@types/node": "^20.12.11", + "@types/react": "^18.3.9", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", + "eslint": "^9.12.0", + "eslint-config-prettier": "^9.1.0", + "eslint-import-resolver-typescript": "^3.6.3", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react-hooks": "^5.0.0", + "globals": "^15.11.0", + "prettier": "^3.3.3", + "ts-node": "^10.9.1", + "typescript": "^5.5.3", + "typescript-eslint": "8.8.1" } } diff --git a/demos/pnpm-lock.yaml b/demos/pnpm-lock.yaml new file mode 100644 index 000000000..056629cca --- /dev/null +++ b/demos/pnpm-lock.yaml @@ -0,0 +1,3379 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@live-compositor/node': + specifier: ^0.1.0 + version: 0.1.0(live-compositor@0.1.0(react@18.3.1))(react@18.3.1) + '@types/fs-extra': + specifier: ^11.0.2 + version: 11.0.4 + '@types/node-fetch': + specifier: ^2.6.11 + version: 2.6.11 + chalk: + specifier: ^4.1.2 + version: 4.1.2 + fs-extra: + specifier: ^11.1.1 + version: 11.2.0 + json-schema-to-typescript: + specifier: ^14.0.4 + version: 14.1.0 + live-compositor: + specifier: ^0.1.0 + version: 0.1.0(react@18.3.1) + node-fetch: + specifier: ^2.7.0 + version: 2.7.0 + node-popup: + specifier: ^0.1.14 + version: 0.1.14 + react: + specifier: ^18.3.1 + version: 18.3.1 + devDependencies: + '@types/node': + specifier: ^20.12.11 + version: 20.16.11 + '@types/react': + specifier: ^18.3.9 + version: 18.3.11 + '@typescript-eslint/eslint-plugin': + specifier: ^8.8.1 + version: 8.9.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/parser': + specifier: ^8.8.1 + version: 8.9.0(eslint@9.12.0)(typescript@5.6.3) + eslint: + specifier: ^9.12.0 + version: 9.12.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.12.0) + eslint-import-resolver-typescript: + specifier: ^3.6.3 + version: 3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.12.0) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.12.0))(eslint@9.12.0)(prettier@3.3.3) + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.0.0(eslint@9.12.0) + globals: + specifier: ^15.11.0 + version: 15.11.0 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + ts-node: + specifier: ^10.9.1 + version: 10.9.2(@types/node@20.16.11)(typescript@5.6.3) + typescript: + specifier: ^5.5.3 + version: 5.6.3 + typescript-eslint: + specifier: 8.8.1 + version: 8.8.1(eslint@9.12.0)(typescript@5.6.3) + +packages: + + '@apidevtools/json-schema-ref-parser@11.7.2': + resolution: {integrity: sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==} + engines: {node: '>= 16'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.18.0': + resolution: {integrity: sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.6.0': + resolution: {integrity: sha512-8I2Q8ykA4J0x0o7cg67FPVnehcqWTBehu/lmY+bolPFHGjh49YzGBMXTvpqVgEbBdvNCSxj6iFgiIyHzf03lzg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.1.0': + resolution: {integrity: sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.12.0': + resolution: {integrity: sha512-eohesHH8WFRUprDNyEREgqP6beG6htMeUYeCpkEgBCieCMme5r9zFWjzAJp//9S+Kub4rqE+jXe9Cp1a7IYIIA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.3': + resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.0': + resolution: {integrity: sha512-2cbWIHbZVEweE853g8jymffCA+NCMiuqeECeBBLm8dg2oFdjuGJhgN4UAbI+6v0CKbbhvtXA4qV8YR5Ji86nmw==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.5': + resolution: {integrity: sha512-KSPA4umqSG4LHYRodq31VDwKAvaTF4xmVlzM8Aeh4PlU1JQ3IG0wiA8C25d3RQ9nJyM3mBHyI53K06VVL/oFFg==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@live-compositor/core@0.1.0': + resolution: {integrity: sha512-0ZqPH3kS1krO633j9930Wr/lBBNj6kdmwsEeOkmatgt9aApzcYTk6rxb2awdn4Oh5JcmDtVBf1zrLzgAT9iwcQ==} + peerDependencies: + live-compositor: ^0.1.0 + + '@live-compositor/node@0.1.0': + resolution: {integrity: sha512-Wdnq5cyWE2rEDy12IVue+98hsrigZtDnZlWrbDLPT29/ERCl2eSFeOSlnAaZvLqw26xmeNAVkjpBXqMjI1O3bg==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + + '@types/lodash@4.17.10': + resolution: {integrity: sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==} + + '@types/node-fetch@2.6.11': + resolution: {integrity: sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==} + + '@types/node@20.16.11': + resolution: {integrity: sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==} + + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + + '@types/react@18.3.11': + resolution: {integrity: sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==} + + '@typescript-eslint/eslint-plugin@8.8.1': + resolution: {integrity: sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/eslint-plugin@8.9.0': + resolution: {integrity: sha512-Y1n621OCy4m7/vTXNlCbMVp87zSd7NH0L9cXD8aIpOaNlzeWxIK4+Q19A68gSmTNRZn92UjocVUWDthGxtqHFg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.8.1': + resolution: {integrity: sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.9.0': + resolution: {integrity: sha512-U+BLn2rqTTHnc4FL3FJjxaXptTxmf9sNftJK62XLz4+GxG3hLHm/SUNaaXP5Y4uTiuYoL5YLy4JBCJe3+t8awQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@8.8.1': + resolution: {integrity: sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/scope-manager@8.9.0': + resolution: {integrity: sha512-bZu9bUud9ym1cabmOYH9S6TnbWRzpklVmwqICeOulTCZ9ue2/pczWzQvt/cGj2r2o1RdKoZbuEMalJJSYw3pHQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.8.1': + resolution: {integrity: sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/type-utils@8.9.0': + resolution: {integrity: sha512-JD+/pCqlKqAk5961vxCluK+clkppHY07IbV3vett97KOV+8C6l+CPEPwpUuiMwgbOz/qrN3Ke4zzjqbT+ls+1Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@8.8.1': + resolution: {integrity: sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/types@8.9.0': + resolution: {integrity: sha512-SjgkvdYyt1FAPhU9c6FiYCXrldwYYlIQLkuc+LfAhCna6ggp96ACncdtlbn8FmnG72tUkXclrDExOpEYf1nfJQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.8.1': + resolution: {integrity: sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.9.0': + resolution: {integrity: sha512-9iJYTgKLDG6+iqegehc5+EqE6sqaee7kb8vWpmHZ86EqwDjmlqNNHeqDVqb9duh+BY6WCNHfIGvuVU3Tf9Db0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@8.8.1': + resolution: {integrity: sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/utils@8.9.0': + resolution: {integrity: sha512-PKgMmaSo/Yg/F7kIZvrgrWa1+Vwn036CdNUvYFEkYbPwOH4i8xvkaRlu148W3vtheWK9ckKRIz7PBP5oUlkrvQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@8.8.1': + resolution: {integrity: sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/visitor-keys@8.9.0': + resolution: {integrity: sha512-Ht4y38ubk4L5/U8xKUBfKNYGmvKvA1CANoxiTRMM+tOLk3lbF3DvzZCxJCRSE+2GdCMSh6zq9VZJc3asc1XuAA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@4.3.0: + resolution: {integrity: sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==} + engines: {node: '>= 4.0.0'} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + buffer-crc32@0.2.13: + resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + carlo@0.9.43: + resolution: {integrity: sha512-m3kCI4ZxYKCGmOoBNnu/Bq+FMZpfYV2P8qWuOcVa2HuxBgS5afG5Efw9D8v7IUhCc+4ox2Eag1BN9ERtGPr7Vg==} + engines: {node: '>=7.6.0'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + cli-color@2.0.4: + resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} + engines: {node: '>=0.10'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-promisify@5.0.0: + resolution: {integrity: sha512-C+d6UdsYDk0lMebHNR4S2NybQMMngAOnOwYBQjTOiv0MkoJMP0Myw2mgpDLBcpfCmRLxyFqYhS/CfOENq4SJhQ==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.3: + resolution: {integrity: sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@5.0.0: + resolution: {integrity: sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-scope@8.1.0: + resolution: {integrity: sha512-14dSvlhaVhKKsa9Fx1l8A17s7ah7Ef7wCakJ10LYk6+GYmP9yDti2oq2SEwcyndt6knfcZyhyxwY3i9yL78EQw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.1.0: + resolution: {integrity: sha512-Q7lok0mqMUSf5a/AdAZkA5a/gHcO6snwQClVNNvFKCAVlxXucdU8pKydU5ZVZjBx5xr37vGbFFWtLQYreLzrZg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.12.0: + resolution: {integrity: sha512-UVIOlTEWxwIopRL1wgSQYdnVDcEvs2wyaO6DGo5mXqe3r16IoCNWkR29iHhyaP4cICWjbgbmFUGAhh0GJRuGZw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + espree@10.2.0: + resolution: {integrity: sha512-upbkBJbckcCNBDBDXEbuhjbP68n+scUd3k/U2EkyM9nw+I/jPiL4cLF/Al06CF96wRltFda16sxDFrxsI1v0/g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + extract-zip@1.7.0: + resolution: {integrity: sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==} + hasBin: true + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.11.0: + resolution: {integrity: sha512-yeyNSjdbyVaWurlwCpcA6XNBrHTMIeDdj0/hnvX/OLJ9ekOXYbLsLinH/MucQyGvNnXhidTdNhTtJaffL2sMfw==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + https-proxy-agent@2.2.4: + resolution: {integrity: sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==} + engines: {node: '>= 4.5.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-bun-module@1.2.1: + resolution: {integrity: sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-to-typescript@14.1.0: + resolution: {integrity: sha512-VIeAFQkn88gFh26MSHWG4uX7TjK/arTw0NVLMZn6vX1WrSF+P6xu5MyEdovu+9PJ0uiS5gm0wzwQvYW9eSq1uw==} + engines: {node: '>=16.0.0'} + hasBin: true + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + live-compositor@0.1.0: + resolution: {integrity: sha512-TAScLUrHcSBAkAzQPsfyqvZ3EDHyETABKnp6E0uY7x1Zsqj+Xz4RkoOPB2cBJDORpSUkQUtj6pbchKUSXQ4Mnw==} + peerDependencies: + react: '*' + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + memoizee@0.4.17: + resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} + engines: {node: '>=0.12'} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + node-popup@0.1.14: + resolution: {integrity: sha512-zmFaETuJn87rKY8Ib7IQVyBDcg9Uh7/GnPLFyPeCU1Tx5KA7Z2SBAs2kdhUBFiMElUzQwqllBRJoikpOf4ee2Q==} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + puppeteer-core@1.20.0: + resolution: {integrity: sha512-akoSCMDVv6BFd/4+dtW6mVgdaRQhy/cmkGzXcx9HAXZqnY9zXYbsfoXMiMpwt3+53U9zFGSjgvsi0mDKNJLfqg==} + engines: {node: '>=6.4.0'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + react-reconciler@0.29.2: + resolution: {integrity: sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^18.3.1 + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + timers-ext@0.1.8: + resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} + engines: {node: '>=0.12'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + ts-api-utils@1.3.0: + resolution: {integrity: sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript-eslint@8.8.1: + resolution: {integrity: sha512-R0dsXFt6t4SAFjUSKFjMh4pXDtq04SsFKCVGDP3ZOzNP7itF0jBcZYU4fMsZr4y7O7V7Nc751dDeESbe4PbQMQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.6.3: + resolution: {integrity: sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@6.2.3: + resolution: {integrity: sha512-jmTjYU0j60B+vHey6TfR3Z7RD61z/hmxBS3VMSGIrroOWXQEneK1zNuotOUrGyBHQj0yrpsLHPWtigEFd13ndA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + +snapshots: + + '@apidevtools/json-schema-ref-parser@11.7.2': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@eslint-community/eslint-utils@4.4.0(eslint@9.12.0)': + dependencies: + eslint: 9.12.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/config-array@0.18.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.6.0': {} + + '@eslint/eslintrc@3.1.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.2.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.12.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.3': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.0': {} + + '@humanfs/node@0.16.5': + dependencies: + '@humanfs/core': 0.19.0 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jsdevtools/ono@7.1.3': {} + + '@live-compositor/core@0.1.0(live-compositor@0.1.0(react@18.3.1))(react@18.3.1)': + dependencies: + live-compositor: 0.1.0(react@18.3.1) + react-reconciler: 0.29.2(react@18.3.1) + transitivePeerDependencies: + - react + + '@live-compositor/node@0.1.0(live-compositor@0.1.0(react@18.3.1))(react@18.3.1)': + dependencies: + '@live-compositor/core': 0.1.0(live-compositor@0.1.0(react@18.3.1))(react@18.3.1) + fs-extra: 11.2.0 + node-fetch: 2.7.0 + tar: 7.4.3 + uuid: 10.0.0 + ws: 8.18.0 + transitivePeerDependencies: + - bufferutil + - encoding + - live-compositor + - react + - utf-8-validate + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@rtsao/scc@1.1.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/estree@1.0.6': {} + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 20.16.11 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 20.16.11 + + '@types/lodash@4.17.10': {} + + '@types/node-fetch@2.6.11': + dependencies: + '@types/node': 20.16.11 + form-data: 4.0.1 + + '@types/node@20.16.11': + dependencies: + undici-types: 6.19.8 + + '@types/prop-types@15.7.13': {} + + '@types/react@18.3.11': + dependencies: + '@types/prop-types': 15.7.13 + csstype: 3.1.3 + + '@typescript-eslint/eslint-plugin@8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.6.3))(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/type-utils': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.8.1 + eslint: 9.12.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.9.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/scope-manager': 8.9.0 + '@typescript-eslint/type-utils': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.9.0 + eslint: 9.12.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.8.1 + debug: 4.3.7 + eslint: 9.12.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.9.0 + '@typescript-eslint/types': 8.9.0 + '@typescript-eslint/typescript-estree': 8.9.0(typescript@5.6.3) + '@typescript-eslint/visitor-keys': 8.9.0 + debug: 4.3.7 + eslint: 9.12.0 + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.8.1': + dependencies: + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/visitor-keys': 8.8.1 + + '@typescript-eslint/scope-manager@8.9.0': + dependencies: + '@typescript-eslint/types': 8.9.0 + '@typescript-eslint/visitor-keys': 8.9.0 + + '@typescript-eslint/type-utils@8.8.1(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.6.3) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + debug: 4.3.7 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/type-utils@8.9.0(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.9.0(typescript@5.6.3) + '@typescript-eslint/utils': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + debug: 4.3.7 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@8.8.1': {} + + '@typescript-eslint/types@8.9.0': {} + + '@typescript-eslint/typescript-estree@8.8.1(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/visitor-keys': 8.8.1 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.9.0(typescript@5.6.3)': + dependencies: + '@typescript-eslint/types': 8.9.0 + '@typescript-eslint/visitor-keys': 8.9.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.3.0(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.8.1(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0) + '@typescript-eslint/scope-manager': 8.8.1 + '@typescript-eslint/types': 8.8.1 + '@typescript-eslint/typescript-estree': 8.8.1(typescript@5.6.3) + eslint: 9.12.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.9.0(eslint@9.12.0)(typescript@5.6.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0) + '@typescript-eslint/scope-manager': 8.9.0 + '@typescript-eslint/types': 8.9.0 + '@typescript-eslint/typescript-estree': 8.9.0(typescript@5.6.3) + eslint: 9.12.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@8.8.1': + dependencies: + '@typescript-eslint/types': 8.8.1 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.9.0': + dependencies: + '@typescript-eslint/types': 8.9.0 + eslint-visitor-keys: 3.4.3 + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + agent-base@4.3.0: + dependencies: + es6-promisify: 5.0.0 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + arg@4.1.3: {} + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + async-limiter@1.0.1: {} + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + balanced-match@1.0.2: {} + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + buffer-crc32@0.2.13: {} + + buffer-from@1.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + carlo@0.9.43: + dependencies: + debug: 4.3.7 + puppeteer-core: 1.20.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chownr@3.0.0: {} + + cli-color@2.0.4: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + memoizee: 0.4.17 + timers-ext: 0.1.8 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + core-util-is@1.0.3: {} + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + + data-uri-to-buffer@4.0.1: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + diff@4.0.2: {} + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + eastasianwidth@0.2.0: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-promise@4.2.8: {} + + es6-promisify@5.0.0: + dependencies: + es6-promise: 4.2.8 + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + es6-weak-map@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@9.1.0(eslint@9.12.0): + dependencies: + eslint: 9.12.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.3.7 + enhanced-resolve: 5.17.1 + eslint: 9.12.0 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0))(eslint@9.12.0) + fast-glob: 3.3.2 + get-tsconfig: 4.8.1 + is-bun-module: 1.2.1 + is-glob: 4.0.3 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.12.0) + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0))(eslint@9.12.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + eslint: 9.12.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.12.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.12.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.9.0(eslint@9.12.0)(typescript@5.6.3))(eslint-plugin-import@2.31.0)(eslint@9.12.0))(eslint@9.12.0) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + string.prototype.trimend: 1.0.8 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.9.0(eslint@9.12.0)(typescript@5.6.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.12.0))(eslint@9.12.0)(prettier@3.3.3): + dependencies: + eslint: 9.12.0 + prettier: 3.3.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.12.0) + + eslint-plugin-react-hooks@5.0.0(eslint@9.12.0): + dependencies: + eslint: 9.12.0 + + eslint-scope@8.1.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.1.0: {} + + eslint@9.12.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@9.12.0) + '@eslint-community/regexpp': 4.11.1 + '@eslint/config-array': 0.18.0 + '@eslint/core': 0.6.0 + '@eslint/eslintrc': 3.1.0 + '@eslint/js': 9.12.0 + '@eslint/plugin-kit': 0.2.3 + '@humanfs/node': 0.16.5 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.3.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint-scope: 8.1.0 + eslint-visitor-keys: 4.1.0 + espree: 10.2.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + + espree@10.2.0: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 4.1.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + + ext@1.7.0: + dependencies: + type: 2.7.3 + + extract-zip@1.7.0: + dependencies: + concat-stream: 1.6.2 + debug: 2.6.9 + mkdirp: 0.5.6 + yauzl: 2.10.0 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fd-slicer@1.1.0: + dependencies: + pend: 1.2.0 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs.realpath@1.0.0: {} + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@14.0.0: {} + + globals@15.11.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.0.2: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + https-proxy-agent@2.2.4: + dependencies: + agent-base: 4.3.0 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-bun-module@1.2.1: + dependencies: + semver: 7.6.3 + + is-callable@1.2.7: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-promise@2.2.2: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + json-buffer@3.0.1: {} + + json-schema-to-typescript@14.1.0: + dependencies: + '@apidevtools/json-schema-ref-parser': 11.7.2 + '@types/json-schema': 7.0.15 + '@types/lodash': 4.17.10 + cli-color: 2.0.4 + glob: 10.4.5 + is-glob: 4.0.3 + js-yaml: 4.1.0 + lodash: 4.17.21 + minimist: 1.2.8 + mkdirp: 3.0.1 + node-fetch: 3.3.2 + prettier: 3.3.3 + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + live-compositor@0.1.0(react@18.3.1): + dependencies: + react: 18.3.1 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-queue@0.1.0: + dependencies: + es5-ext: 0.10.64 + + make-error@1.3.6: {} + + memoizee@0.4.17: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.8 + + merge2@1.4.1: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@2.6.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@7.1.2: {} + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@3.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + natural-compare@1.4.0: {} + + next-tick@1.1.0: {} + + node-domexception@1.0.0: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-popup@0.1.14: + dependencies: + carlo: 0.9.43 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + object-inspect@1.13.2: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + pend@1.2.0: {} + + picomatch@2.3.1: {} + + possible-typed-array-names@1.0.0: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.3.3: {} + + process-nextick-args@2.0.1: {} + + progress@2.0.3: {} + + proxy-from-env@1.1.0: {} + + punycode@2.3.1: {} + + puppeteer-core@1.20.0: + dependencies: + debug: 4.3.7 + extract-zip: 1.7.0 + https-proxy-agent: 2.2.4 + mime: 2.6.0 + progress: 2.0.3 + proxy-from-env: 1.1.0 + rimraf: 2.7.1 + ws: 6.2.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + queue-microtask@1.2.3: {} + + react-reconciler@0.29.2(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + semver@6.3.1: {} + + semver@7.6.3: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + signal-exit@4.1.0: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.0 + + tapable@2.2.1: {} + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + text-table@0.2.0: {} + + timers-ext@0.1.8: + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + tr46@0.0.3: {} + + ts-api-utils@1.3.0(typescript@5.6.3): + dependencies: + typescript: 5.6.3 + + ts-node@10.9.2(@types/node@20.16.11)(typescript@5.6.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.16.11 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.6.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@2.8.0: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type@2.7.3: {} + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typedarray@0.0.6: {} + + typescript-eslint@8.8.1(eslint@9.12.0)(typescript@5.6.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.8.1(@typescript-eslint/parser@8.8.1(eslint@9.12.0)(typescript@5.6.3))(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/parser': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + '@typescript-eslint/utils': 8.8.1(eslint@9.12.0)(typescript@5.6.3) + optionalDependencies: + typescript: 5.6.3 + transitivePeerDependencies: + - eslint + - supports-color + + typescript@5.6.3: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@6.19.8: {} + + universalify@2.0.1: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + util-deprecate@1.0.2: {} + + uuid@10.0.0: {} + + v8-compile-cache-lib@3.0.1: {} + + web-streams-polyfill@3.3.3: {} + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@6.2.3: + dependencies: + async-limiter: 1.0.1 + + ws@8.18.0: {} + + yallist@5.0.0: {} + + yauzl@2.10.0: + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} diff --git a/demos/tsconfig.json b/demos/tsconfig.json index 569e1ebdf..1897c55a1 100644 --- a/demos/tsconfig.json +++ b/demos/tsconfig.json @@ -1,13 +1,13 @@ { - "compilerOptions": { - "module": "commonjs", - "strict": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "esModuleInterop": true, - "declaration": true, - "jsx": "react-jsx" - } + "compilerOptions": { + "module": "commonjs", + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "esModuleInterop": true, + "declaration": true, + "jsx": "react-jsx" + } } diff --git a/demos/utils/ffmpeg.ts b/demos/utils/ffmpeg.ts index bf08a1ce8..0c2e0b801 100644 --- a/demos/utils/ffmpeg.ts +++ b/demos/utils/ffmpeg.ts @@ -1,6 +1,7 @@ -import { SpawnPromise, sleepAsync, spawn } from './utils'; +import type { SpawnPromise } from './utils'; +import { sleepAsync, spawn } from './utils'; import path from 'path'; -import fs from 'fs-extra'; +import { mkdirp, writeFile } from 'fs-extra'; const COMPOSITOR_DIR = path.join(__dirname, '../.live_compositor'); @@ -9,7 +10,7 @@ export async function ffplayStartPlayerAsync( audio_port: number | undefined = undefined ): Promise { let sdpFilePath; - await fs.mkdirp(COMPOSITOR_DIR); + await mkdirp(COMPOSITOR_DIR); if (audio_port === undefined) { sdpFilePath = path.join(COMPOSITOR_DIR, `video_input_${video_port}.sdp`); await writeVideoSdpFile('127.0.0.1', video_port, sdpFilePath); @@ -75,7 +76,7 @@ async function writeVideoAudioSdpFile( audio_port: number, destination: string ): Promise { - await fs.writeFile( + await writeFile( destination, ` v=0 @@ -94,7 +95,7 @@ a=rtcp-mux } async function writeVideoSdpFile(ip: string, port: number, destination: string): Promise { - await fs.writeFile( + await writeFile( destination, ` v=0 diff --git a/demos/utils/utils.ts b/demos/utils/utils.ts index 9d1b4cb36..11fd18ad4 100644 --- a/demos/utils/utils.ts +++ b/demos/utils/utils.ts @@ -1,8 +1,9 @@ import fetch from 'node-fetch'; -import fs from 'fs-extra'; +import fs, { mkdirp } from 'fs-extra'; import { promisify } from 'util'; import { Stream } from 'stream'; -import { ChildProcess, spawn as nodeSpawn } from 'child_process'; +import type { ChildProcess } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; import { cwd } from 'process'; import path from 'path'; @@ -68,7 +69,7 @@ export async function downloadAsync(url: string, destination: string): Promise= 400) { const err: any = new Error(`Request to ${url} failed. \n${response.body}`); diff --git a/docs/.prettierrc.js b/docs/.prettierrc.js new file mode 100644 index 000000000..6d74d8619 --- /dev/null +++ b/docs/.prettierrc.js @@ -0,0 +1,11 @@ +const config = { + printWidth: 100, + tabWidth: 2, + singleQuote: true, + bracketSameLine: true, + trailingComma: "es5", + arrowParens: "avoid", + endOfLine: "auto" +}; + +export default config; \ No newline at end of file diff --git a/docs/package-lock.json b/docs/package-lock.json index e079c334b..3355a1773 100644 --- a/docs/package-lock.json +++ b/docs/package-lock.json @@ -9158,9 +9158,9 @@ } }, "node_modules/http-proxy-middleware": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz", - "integrity": "sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.7.tgz", + "integrity": "sha512-fgVY8AV7qU7z/MmXJ/rxwbrtQH4jBQ9m7kp3llF0liB7glmFeVZFBepQb32T3y8n8k2+AEYuMPCpinYW+/CuRA==", "dependencies": { "@types/http-proxy": "^1.17.8", "http-proxy": "^1.18.1", diff --git a/docs/pages/deployment/configuration.md b/docs/pages/deployment/configuration.md index be638d4b5..913c53ba7 100644 --- a/docs/pages/deployment/configuration.md +++ b/docs/pages/deployment/configuration.md @@ -128,3 +128,7 @@ Increasing this value always increases the latency of the stream by the same amo ::: Defaults to `80ms` (about 5 frames in 60 fps). + +### `LIVE_COMPOSITOR_LOG_FILE` + +Path to the file were Live Compositor logs should be written. Setting this option does not disable logging to the standard output. diff --git a/docs/src/components/ExampleSceneJsx.tsx b/docs/src/components/ExampleSceneJsx.tsx index 1ee85c0d0..9a7d53b2d 100644 --- a/docs/src/components/ExampleSceneJsx.tsx +++ b/docs/src/components/ExampleSceneJsx.tsx @@ -21,17 +21,14 @@ function Example() { - + LiveCompositor 😃😍 + ); } diff --git a/generate/src/compositor_instance.rs b/generate/src/compositor_instance.rs index 6970c1191..aa36656ce 100644 --- a/generate/src/compositor_instance.rs +++ b/generate/src/compositor_instance.rs @@ -1,11 +1,6 @@ use anyhow::{anyhow, Result}; use crossbeam_channel::Sender; -use live_compositor::{ - config::{read_config, LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, - server::run_api, - state::ApiState, -}; +use live_compositor::{config::read_config, logger, server::run_api, state::ApiState}; use reqwest::StatusCode; use std::{ env, @@ -113,10 +108,6 @@ fn init_compositor_prerequisites() { GLOBAL_PREREQUISITES_INITIALIZED.get_or_init(|| { env::set_var("LIVE_COMPOSITOR_WEB_RENDERER_ENABLE", "0"); ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "warn,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); + logger::init_logger(read_config().logger); }); } diff --git a/integration_tests/examples/encoded_channel_output.rs b/integration_tests/examples/encoded_channel_output.rs index f9312eb6b..d384c2371 100644 --- a/integration_tests/examples/encoded_channel_output.rs +++ b/integration_tests/examples/encoded_channel_output.rs @@ -23,11 +23,7 @@ use compositor_render::{ InputId, OutputId, Resolution, }; use integration_tests::examples::download_file; -use live_compositor::{ - config::{read_config, LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, - state::ApiState, -}; +use live_compositor::{config::read_config, logger, state::ApiState}; const BUNNY_FILE_URL: &str = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; @@ -38,13 +34,9 @@ const BUNNY_FILE_PATH: &str = "examples/assets/BigBuckBunny.mp4"; // Data read from channels are dumped into files as it is without any timestamp data. fn main() { ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "info,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); - let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut config = read_config(); + logger::init_logger(config.logger.clone()); + let root_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")); config.queue_options.ahead_of_time_processing = true; // no chromium support, so we can ignore _event_loop let (state, _event_loop) = ApiState::new(config).unwrap_or_else(|err| { diff --git a/integration_tests/examples/manual_graphics_initialization.rs b/integration_tests/examples/manual_graphics_initialization.rs index 236edd7f9..2ae7e096f 100644 --- a/integration_tests/examples/manual_graphics_initialization.rs +++ b/integration_tests/examples/manual_graphics_initialization.rs @@ -9,27 +9,18 @@ fn main() { }; use live_compositor::config::read_config; - let graphics_context = - GraphicsContext::new(false, wgpu::Features::default(), wgpu::Limits::default()).unwrap(); + let graphics_context = GraphicsContext::new( + false, + wgpu::Features::default(), + wgpu::Limits::default(), + None, + ) + .unwrap(); let _device = graphics_context.device.clone(); let _queue = graphics_context.queue.clone(); - - let _adapter = graphics_context - .vulkan_ctx - .as_ref() - .unwrap() - .wgpu_ctx - .adapter - .clone(); - - let _instance = graphics_context - .vulkan_ctx - .as_ref() - .unwrap() - .wgpu_ctx - .instance - .clone(); + let _adapter = graphics_context.adapter.clone(); + let _instance = graphics_context.instance.clone(); let config = read_config(); diff --git a/integration_tests/examples/raw_channel_input.rs b/integration_tests/examples/raw_channel_input.rs index b458f8c51..837785fd1 100644 --- a/integration_tests/examples/raw_channel_input.rs +++ b/integration_tests/examples/raw_channel_input.rs @@ -29,8 +29,8 @@ use compositor_render::{ }; use integration_tests::{gstreamer::start_gst_receive_tcp, test_input::TestInput}; use live_compositor::{ - config::{read_config, LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, + config::read_config, + logger::{self}, }; const VIDEO_OUTPUT_PORT: u16 = 8002; @@ -38,13 +38,9 @@ const VIDEO_OUTPUT_PORT: u16 = 8002; // Start simple pipeline with input that sends PCM audio and wgpu::Textures via Rust channel. fn main() { ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "info,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); let config = read_config(); - let ctx = GraphicsContext::new(false, Default::default(), Default::default()).unwrap(); + logger::init_logger(config.logger); + let ctx = GraphicsContext::new(false, Default::default(), Default::default(), None).unwrap(); let (wgpu_device, wgpu_queue) = (ctx.device.clone(), ctx.queue.clone()); // no chromium support, so we can ignore _event_loop let (pipeline, _event_loop) = Pipeline::new(Options { @@ -201,12 +197,12 @@ fn create_texture(index: usize, device: &wgpu::Device, queue: &wgpu::Queue) -> A mip_level_count: 1, sample_count: 1, dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Rgba8Unorm, + format: wgpu::TextureFormat::Rgba8UnormSrgb, usage: wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::COPY_DST | wgpu::TextureUsages::COPY_SRC | wgpu::TextureUsages::TEXTURE_BINDING, - view_formats: &[wgpu::TextureFormat::Rgba8Unorm], + view_formats: &[wgpu::TextureFormat::Rgba8UnormSrgb], }); queue.write_texture( diff --git a/integration_tests/examples/raw_channel_output.rs b/integration_tests/examples/raw_channel_output.rs index 43bfc6037..0a8f8b78d 100644 --- a/integration_tests/examples/raw_channel_output.rs +++ b/integration_tests/examples/raw_channel_output.rs @@ -31,8 +31,8 @@ use crossbeam_channel::bounded; use image::{codecs::png::PngEncoder, ColorType, ImageEncoder}; use integration_tests::{examples::download_file, read_rgba_texture}; use live_compositor::{ - config::{read_config, LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, + config::read_config, + logger::{self}, }; const BUNNY_FILE_URL: &str = @@ -50,14 +50,10 @@ fn root_dir() -> PathBuf { // - read audio samples and write raw value using debug formatting fn main() { ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "info,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); + logger::init_logger(read_config().logger); let mut config = read_config(); config.queue_options.ahead_of_time_processing = true; - let ctx = GraphicsContext::new(false, Default::default(), Default::default()).unwrap(); + let ctx = GraphicsContext::new(false, Default::default(), Default::default(), None).unwrap(); let (wgpu_device, wgpu_queue) = (ctx.device.clone(), ctx.queue.clone()); // no chromium support, so we can ignore _event_loop let (pipeline, _event_loop) = Pipeline::new(Options { diff --git a/integration_tests/examples/rescaler_border_transition.rs b/integration_tests/examples/rescaler_border_transition.rs new file mode 100644 index 000000000..5e38a5b2e --- /dev/null +++ b/integration_tests/examples/rescaler_border_transition.rs @@ -0,0 +1,154 @@ +use anyhow::Result; +use compositor_api::types::Resolution; +use serde_json::json; +use std::{ + thread::{self}, + time::Duration, +}; + +use integration_tests::{ + examples::{self, run_example, TestSample}, + ffmpeg::{start_ffmpeg_receive, start_ffmpeg_send}, +}; + +const VIDEO_RESOLUTION: Resolution = Resolution { + width: 1280, + height: 720, +}; + +const IP: &str = "127.0.0.1"; +const INPUT_PORT: u16 = 8002; +const OUTPUT_PORT: u16 = 8004; + +fn main() { + run_example(client_code); +} + +fn client_code() -> Result<()> { + start_ffmpeg_receive(Some(OUTPUT_PORT), None)?; + + examples::post( + "input/input_1/register", + &json!({ + "type": "rtp_stream", + "port": INPUT_PORT, + "video": { + "decoder": "ffmpeg_h264" + } + }), + )?; + + examples::post( + "image/example_image/register", + &json!({ + "asset_type": "gif", + "url": "https://gifdb.com/images/high/rust-logo-on-fire-o41c0v9om8drr8dv.gif", + }), + )?; + + let scene1 = json!({ + "type": "view", + "background_color_rgba": "#42daf5ff", + "children": [ + { + "type": "rescaler", + "id": "resized", + "width": VIDEO_RESOLUTION.width, + "height": VIDEO_RESOLUTION.height, + "top": 0.0, + "right": 0.0, + "mode": "fill", + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_y": 40, + "offset_x": 0, + "blur_radius": 40, + "color_rgba": "#00000088", + } + ], + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + }); + + let scene2 = json!({ + "type": "view", + "background_color_rgba": "#42daf5ff", + "children": [ + { + "type": "rescaler", + "id": "resized", + "width": 300, + "height": 300, + "top": (VIDEO_RESOLUTION.height as f32 - 330.0) / 2.0 , + "right": (VIDEO_RESOLUTION.width as f32 - 330.0) / 2.0, + "mode": "fill", + "border_radius": 50, + "border_width": 15, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_y": 40, + "offset_x": 0, + "blur_radius": 40, + "color_rgba": "#00000088", + } + ], + "transition": { + "duration_ms": 1500, + "easing_function": { + "function_name": "cubic_bezier", + "points": [0.33, 1, 0.68, 1] + } + }, + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + }); + + examples::post( + "output/output_1/register", + &json!({ + "type": "rtp_stream", + "ip": IP, + "port": OUTPUT_PORT, + "video": { + "resolution": { + "width": VIDEO_RESOLUTION.width, + "height": VIDEO_RESOLUTION.height, + }, + "encoder": { + "type": "ffmpeg_h264", + "preset": "ultrafast" + }, + "initial": { + "root": scene1 + } + } + }), + )?; + + examples::post("start", &json!({}))?; + + start_ffmpeg_send(IP, Some(INPUT_PORT), None, TestSample::TestPattern)?; + + thread::sleep(Duration::from_secs(5)); + + examples::post( + "output/output_1/update", + &json!({ + "video": { + "root": scene2, + } + }), + )?; + + Ok(()) +} diff --git a/integration_tests/examples/view_border_transition.rs b/integration_tests/examples/view_border_transition.rs new file mode 100644 index 000000000..72ed6f2fd --- /dev/null +++ b/integration_tests/examples/view_border_transition.rs @@ -0,0 +1,166 @@ +use anyhow::Result; +use compositor_api::types::Resolution; +use serde_json::json; +use std::{ + thread::{self}, + time::Duration, +}; + +use integration_tests::{ + examples::{self, run_example, TestSample}, + ffmpeg::{start_ffmpeg_receive, start_ffmpeg_send}, +}; + +const VIDEO_RESOLUTION: Resolution = Resolution { + width: 1280, + height: 720, +}; + +const IP: &str = "127.0.0.1"; +const INPUT_PORT: u16 = 8002; +const OUTPUT_PORT: u16 = 8004; + +fn main() { + run_example(client_code); +} + +fn client_code() -> Result<()> { + start_ffmpeg_receive(Some(OUTPUT_PORT), None)?; + + examples::post( + "input/input_1/register", + &json!({ + "type": "rtp_stream", + "port": INPUT_PORT, + "video": { + "decoder": "ffmpeg_h264" + } + }), + )?; + + examples::post( + "image/example_image/register", + &json!({ + "asset_type": "gif", + "url": "https://gifdb.com/images/high/rust-logo-on-fire-o41c0v9om8drr8dv.gif", + }), + )?; + + let scene1 = json!({ + "type": "view", + "background_color_rgba": "#42daf5ff", + "children": [ + { + "type": "view", + "id": "resized", + "width": VIDEO_RESOLUTION.width, + "height": VIDEO_RESOLUTION.height, + "top": 0.0, + "right": 0.0, + "background_color_rgba": "#0000FFFF", + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_y": 40, + "offset_x": 0, + "blur_radius": 40, + "color_rgba": "#00000088", + } + ], + "children": [ + { + "type": "rescaler", + "mode": "fill", + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + } + ] + }); + + let scene2 = json!({ + "type": "view", + "background_color_rgba": "#42daf5ff", + "children": [ + { + "type": "view", + "id": "resized", + "width": 300, + "height": 300, + "top": (VIDEO_RESOLUTION.height as f32 - 330.0) / 2.0 , + "right": (VIDEO_RESOLUTION.width as f32 - 330.0) / 2.0, + "border_radius": 50, + "border_width": 15, + "background_color_rgba": "#0000FFFF", + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_y": 40, + "offset_x": 0, + "blur_radius": 40, + "color_rgba": "#00000088", + } + ], + "transition": { + "duration_ms": 1500, + "easing_function": { + "function_name": "cubic_bezier", + "points": [0.33, 1, 0.68, 1] + } + }, + "children": [ + { + "type": "rescaler", + "mode": "fill", + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + } + ] + }); + + examples::post( + "output/output_1/register", + &json!({ + "type": "rtp_stream", + "ip": IP, + "port": OUTPUT_PORT, + "video": { + "resolution": { + "width": VIDEO_RESOLUTION.width, + "height": VIDEO_RESOLUTION.height, + }, + "encoder": { + "type": "ffmpeg_h264", + "preset": "ultrafast" + }, + "initial": { + "root": scene1 + } + } + }), + )?; + + examples::post("start", &json!({}))?; + + start_ffmpeg_send(IP, Some(INPUT_PORT), None, TestSample::TestPattern)?; + + thread::sleep(Duration::from_secs(5)); + + examples::post( + "output/output_1/update", + &json!({ + "video": { + "root": scene2, + } + }), + )?; + + Ok(()) +} diff --git a/integration_tests/examples/vulkan.rs b/integration_tests/examples/vulkan.rs index 90150fb9f..60496a596 100644 --- a/integration_tests/examples/vulkan.rs +++ b/integration_tests/examples/vulkan.rs @@ -1,17 +1,13 @@ use anyhow::Result; use integration_tests::examples::download_all_assets; use live_compositor::{ - config::{LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, + config::read_config, + logger::{self}, }; fn main() { ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "info,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); + logger::init_logger(read_config().logger); download_all_assets().unwrap(); @@ -74,7 +70,7 @@ fn client_code() -> Result<()> { }; const IP: &str = "127.0.0.1"; - const INPUT_PORT: u16 = 8002; + const INPUT_PORT: u16 = 8006; const OUTPUT_PORT: u16 = 8004; const VIDEOS: u16 = 6; @@ -103,12 +99,12 @@ fn client_code() -> Result<()> { let mut children = Vec::new(); - for i in 1..VIDEOS + 1 { + for i in 0..VIDEOS { let input_id = InputId(format!("input_{i}").into()); let input_options = RegisterInputOptions { input_options: InputOptions::Rtp(RtpReceiverOptions { - port: RequestedPort::Exact(INPUT_PORT + 2 + 2 * i), + port: RequestedPort::Exact(INPUT_PORT + 2 * i), transport_protocol: TransportProtocol::Udp, stream: RtpStream { video: Some(InputVideoStream { @@ -175,13 +171,8 @@ fn client_code() -> Result<()> { Pipeline::start(&pipeline); - for i in 1..VIDEOS + 1 { - start_ffmpeg_send( - IP, - Some(INPUT_PORT + 2 + 2 * i), - None, - TestSample::BigBuckBunny, - )?; + for i in 0..VIDEOS { + start_ffmpeg_send(IP, Some(INPUT_PORT + 2 * i), None, TestSample::BigBuckBunny)?; } let event_loop_fallback = || { diff --git a/integration_tests/src/compositor_instance.rs b/integration_tests/src/compositor_instance.rs index 8c707f9e1..9f90e4244 100644 --- a/integration_tests/src/compositor_instance.rs +++ b/integration_tests/src/compositor_instance.rs @@ -1,8 +1,8 @@ use anyhow::{anyhow, Result}; use crossbeam_channel::Sender; use live_compositor::{ - config::{read_config, Config, LoggerConfig, LoggerFormat}, - logger::{self, FfmpegLogLevel}, + config::{read_config, Config}, + logger::{self}, server::run_api, state::ApiState, }; @@ -112,10 +112,7 @@ fn init_compositor_prerequisites() { GLOBAL_PREREQUISITES_INITIALIZED.get_or_init(|| { env::set_var("LIVE_COMPOSITOR_WEB_RENDERER_ENABLE", "0"); ffmpeg_next::format::network::init(); - logger::init_logger(LoggerConfig { - ffmpeg_logger_level: FfmpegLogLevel::Info, - format: LoggerFormat::Compact, - level: "info,wgpu_hal=warn,wgpu_core=warn".to_string(), - }); + let config = read_config(); + logger::init_logger(config.logger); }); } diff --git a/integration_tests/src/tests/offline_processing.rs b/integration_tests/src/tests/offline_processing.rs index 2cb0c72e9..fd964b694 100644 --- a/integration_tests/src/tests/offline_processing.rs +++ b/integration_tests/src/tests/offline_processing.rs @@ -123,7 +123,7 @@ pub fn offline_processing() -> Result<()> { if !(1.9..=2.1).contains(&duration) { return Err(anyhow!("Invalid duration: {}", duration)); } - if !(930_000..=1_000_000).contains(&bit_rate) { + if !(1_000_000..=1_015_000).contains(&bit_rate) { return Err(anyhow!("Invalid bit rate: {}", bit_rate)); } diff --git a/integration_tests/src/tests/required_inputs.rs b/integration_tests/src/tests/required_inputs.rs index ca8320df0..c6a167027 100644 --- a/integration_tests/src/tests/required_inputs.rs +++ b/integration_tests/src/tests/required_inputs.rs @@ -1,8 +1,9 @@ use std::{thread, time::Duration}; use crate::{ - compare_video_dumps, input_dump_from_disk, split_rtp_packet_dump, CommunicationProtocol, - CompositorInstance, OutputReceiver, PacketSender, VideoValidationConfig, + compare_audio_dumps, compare_video_dumps, input_dump_from_disk, split_rtp_packet_dump, + AudioValidationConfig, CommunicationProtocol, CompositorInstance, OutputReceiver, PacketSender, + VideoValidationConfig, }; use anyhow::Result; use serde_json::json; @@ -12,8 +13,8 @@ use serde_json::json; /// /// Show `input_1` and `input_2` side by side for 20 seconds. #[test] -pub fn required_inputs_no_offset() -> Result<()> { - const OUTPUT_DUMP_FILE: &str = "required_inputs_no_offset_output.rtp"; +pub fn required_video_inputs_no_offset() -> Result<()> { + const OUTPUT_DUMP_FILE: &str = "required_video_inputs_no_offset_output.rtp"; let instance = CompositorInstance::start(None); let input_1_port = instance.get_port(); let input_2_port = instance.get_port(); @@ -129,8 +130,8 @@ pub fn required_inputs_no_offset() -> Result<()> { /// /// Show `input_1` and `input_2` side by side for 20 seconds. #[test] -pub fn required_inputs_with_offset() -> Result<()> { - const OUTPUT_DUMP_FILE: &str = "required_inputs_with_offset_output.rtp"; +pub fn required_video_inputs_with_offset() -> Result<()> { + const OUTPUT_DUMP_FILE: &str = "required_video_inputs_with_offset_output.rtp"; let instance = CompositorInstance::start(None); let input_1_port = instance.get_port(); let input_2_port = instance.get_port(); @@ -244,6 +245,275 @@ pub fn required_inputs_with_offset() -> Result<()> { Ok(()) } +/// Required inputs with some packets delayed. +/// +/// Countdown from 10 from the beginning +#[test] +pub fn required_audio_inputs_no_offset() -> Result<()> { + const OUTPUT_DUMP_FILE: &str = "required_audio_inputs_no_offset_output.rtp"; + let instance = CompositorInstance::start(None); + let input_1_port = instance.get_port(); + let output_port = instance.get_port(); + + instance.send_request( + "output/output_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": output_port, + "audio": { + "initial": { + "inputs": [ + { + "input_id": "input_1", + "volume": 1.0, + }, + ] + }, + "encoder": { + "type": "opus", + "channels": "stereo", + } + }, + }), + )?; + + instance.send_request( + "output/output_1/unregister", + json!({ + "schedule_time_ms": 10000, + }), + )?; + + let output_receiver = OutputReceiver::start(output_port, CommunicationProtocol::Tcp)?; + + instance.send_request( + "input/input_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": input_1_port, + "audio": { + "decoder": "opus" + }, + "required": true, + }), + )?; + + let mut input_sender = PacketSender::new(CommunicationProtocol::Tcp, input_1_port)?; + let input_dump = input_dump_from_disk("countdown_audio.rtp")?; + let (input_first_part, input_second_part) = + split_rtp_packet_dump(input_dump, Duration::from_secs(1))?; + + let input_handle = thread::spawn(move || { + input_sender.send(&input_first_part).unwrap(); + thread::sleep(Duration::from_secs(3)); + input_sender.send(&input_second_part).unwrap(); + }); + + instance.send_request("start", json!({}))?; + + input_handle.join().unwrap(); + let new_output_dump = output_receiver.wait_for_output()?; + + compare_audio_dumps( + OUTPUT_DUMP_FILE, + &new_output_dump, + AudioValidationConfig { + sampling_intervals: vec![ + Duration::from_millis(0)..Duration::from_millis(2000), + Duration::from_millis(2000)..Duration::from_millis(4000), + Duration::from_millis(6000)..Duration::from_millis(8000), + ], + ..Default::default() + }, + )?; + + Ok(()) +} + +/// Required inputs with some packets delayed. Offset set to 1000ms. +/// +/// Countdown from 10 delayed by one second +#[test] +pub fn required_audio_inputs_with_offset() -> Result<()> { + const OUTPUT_DUMP_FILE: &str = "required_audio_inputs_with_offset_output.rtp"; + let instance = CompositorInstance::start(None); + let input_1_port = instance.get_port(); + let output_port = instance.get_port(); + + instance.send_request( + "output/output_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": output_port, + "audio": { + "initial": { + "inputs": [ + { + "input_id": "input_1", + "volume": 1.0, + }, + ] + }, + "encoder": { + "type": "opus", + "channels": "stereo", + } + }, + }), + )?; + + instance.send_request( + "output/output_1/unregister", + json!({ + "schedule_time_ms": 10000, + }), + )?; + + let output_receiver = OutputReceiver::start(output_port, CommunicationProtocol::Tcp)?; + + instance.send_request( + "input/input_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": input_1_port, + "audio": { + "decoder": "opus" + }, + "offset_ms": 1000, + "required": true, + }), + )?; + + let mut input_sender = PacketSender::new(CommunicationProtocol::Tcp, input_1_port)?; + let input_dump = input_dump_from_disk("countdown_audio.rtp")?; + let (input_first_part, input_second_part) = + split_rtp_packet_dump(input_dump, Duration::from_secs(1))?; + + let input_handle = thread::spawn(move || { + input_sender.send(&input_first_part).unwrap(); + thread::sleep(Duration::from_secs(3)); + input_sender.send(&input_second_part).unwrap(); + }); + + instance.send_request("start", json!({}))?; + + input_handle.join().unwrap(); + let new_output_dump = output_receiver.wait_for_output()?; + + compare_audio_dumps( + OUTPUT_DUMP_FILE, + &new_output_dump, + AudioValidationConfig { + sampling_intervals: vec![ + Duration::from_millis(0)..Duration::from_millis(2000), + Duration::from_millis(2000)..Duration::from_millis(4000), + Duration::from_millis(6000)..Duration::from_millis(8000), + ], + ..Default::default() + }, + )?; + + Ok(()) +} + +/// Required inputs with some packets delayed and some dropped. Offset set to 1000ms. +/// +/// Countdown from 10 +/// - 1 seconds of silence +/// - 1 second of audio (from the start of the recording) +/// - 2 seconds of silence (cuts of part of "10" and "9" from countdown) +/// - remaining part of audio (2 seconds from previous step are missing) +#[test] +pub fn required_audio_inputs_with_offset_missing_data() -> Result<()> { + const OUTPUT_DUMP_FILE: &str = "required_audio_inputs_with_offset_missing_data_output.rtp"; + let instance = CompositorInstance::start(None); + let input_1_port = instance.get_port(); + let output_port = instance.get_port(); + + instance.send_request( + "output/output_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": output_port, + "audio": { + "initial": { + "inputs": [ + { + "input_id": "input_1", + "volume": 1.0, + }, + ] + }, + "encoder": { + "type": "opus", + "channels": "stereo", + } + }, + }), + )?; + + instance.send_request( + "output/output_1/unregister", + json!({ + "schedule_time_ms": 10000, + }), + )?; + + let output_receiver = OutputReceiver::start(output_port, CommunicationProtocol::Tcp)?; + + instance.send_request( + "input/input_1/register", + json!({ + "type": "rtp_stream", + "transport_protocol": "tcp_server", + "port": input_1_port, + "audio": { + "decoder": "opus" + }, + "offset_ms": 1000, + "required": true, + }), + )?; + + let mut input_sender = PacketSender::new(CommunicationProtocol::Tcp, input_1_port)?; + let input_dump = input_dump_from_disk("countdown_audio.rtp")?; + let (input_first_part, input_second_part) = + split_rtp_packet_dump(input_dump, Duration::from_secs(1))?; + let (_dropped_2_seconds, input_second_part_2) = + split_rtp_packet_dump(input_second_part, Duration::from_secs(2))?; + + let input_handle = thread::spawn(move || { + input_sender.send(&input_first_part).unwrap(); + thread::sleep(Duration::from_secs(3)); + input_sender.send(&input_second_part_2).unwrap(); + }); + + instance.send_request("start", json!({}))?; + + input_handle.join().unwrap(); + let new_output_dump = output_receiver.wait_for_output()?; + + compare_audio_dumps( + OUTPUT_DUMP_FILE, + &new_output_dump, + AudioValidationConfig { + sampling_intervals: vec![ + Duration::from_millis(0)..Duration::from_millis(2000), + Duration::from_millis(2000)..Duration::from_millis(4000), + Duration::from_millis(6000)..Duration::from_millis(8000), + ], + ..Default::default() + }, + )?; + + Ok(()) +} + /// Optional inputs with some packets delayed in the middle /// No offset /// diff --git a/schemas/scene.schema.json b/schemas/scene.schema.json index 0b2d97ccf..63b743f06 100644 --- a/schemas/scene.schema.json +++ b/schemas/scene.schema.json @@ -116,7 +116,7 @@ } }, "width": { - "description": "Width of a component in pixels. Exact behavior might be different based on the parent\ncomponent:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", + "description": "Width of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", "type": [ "number", "null" @@ -124,7 +124,7 @@ "format": "float" }, "height": { - "description": "Height of a component in pixels. Exact behavior might be different based on the parent\ncomponent:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", + "description": "Height of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", "type": [ "number", "null" @@ -143,7 +143,7 @@ ] }, "top": { - "description": "Distance in pixels between this component's top edge and its parent's top edge.\nIf this field is defined, then the component will ignore a layout defined by its parent.", + "description": "Distance in pixels between this component's top edge and its parent's top edge (including a border).\nIf this field is defined, then the component will ignore a layout defined by its parent.", "type": [ "number", "null" @@ -151,7 +151,7 @@ "format": "float" }, "left": { - "description": "Distance in pixels between this component's left edge and its parent's left edge.\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", + "description": "Distance in pixels between this component's left edge and its parent's left edge (including a border).\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", "type": [ "number", "null" @@ -159,7 +159,7 @@ "format": "float" }, "bottom": { - "description": "Distance in pixels between the bottom edge of this component and the bottom edge of its parent.\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", + "description": "Distance in pixels between the bottom edge of this component and the bottom edge of its\nparent (including a border). If this field is defined, this element will be absolutely\npositioned, instead of being laid out by its parent.", "type": [ "number", "null" @@ -214,6 +214,43 @@ "type": "null" } ] + }, + "border_radius": { + "description": "(**default=`0.0`**) Radius of a rounded corner.", + "type": [ + "number", + "null" + ], + "format": "float" + }, + "border_width": { + "description": "(**default=`0.0`**) Border width.", + "type": [ + "number", + "null" + ], + "format": "float" + }, + "border_color_rgba": { + "description": "(**default=`\"#00000000\"`**) Border color in a `\"#RRGGBBAA\"` format.", + "anyOf": [ + { + "$ref": "#/definitions/RGBAColor" + }, + { + "type": "null" + } + ] + }, + "box_shadow": { + "description": "List of box shadows.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/BoxShadow" + } } }, "additionalProperties": false @@ -254,7 +291,7 @@ } }, "instance_id": { - "description": "Id of a web renderer instance. It identifies an instance registered using a [`register web renderer`](../routes.md#register-web-renderer-instance) request.\n\n:::warning\nYou can only refer to specific instances in one Component at a time.\n:::", + "description": "Id of a web renderer instance. It identifies an instance registered using a\n[`register web renderer`](../routes.md#register-web-renderer-instance) request.\n\n:::warning\nYou can only refer to specific instances in one Component at a time.\n:::", "allOf": [ { "$ref": "#/definitions/RendererId" @@ -308,7 +345,7 @@ ] }, "shader_param": { - "description": "Object that will be serialized into a `struct` and passed inside the shader as:\n\n```wgsl\n@group(1) @binding(0) var\n```\n:::note\nThis object's structure must match the structure defined in a shader source code. Currently, we do not handle memory layout automatically.\nTo achieve the correct memory alignment, you might need to pad your data with additional fields. See [WGSL documentation](https://www.w3.org/TR/WGSL/#alignment-and-size) for more details.\n:::", + "description": "Object that will be serialized into a `struct` and passed inside the shader as:\n\n```wgsl\n@group(1) @binding(0) var\n```\n:::note\nThis object's structure must match the structure defined in a shader source code.\nCurrently, we do not handle memory layout automatically. To achieve the correct memory\nalignment, you might need to pad your data with additional fields. See\n[WGSL documentation](https://www.w3.org/TR/WGSL/#alignment-and-size) for more details.\n:::", "anyOf": [ { "$ref": "#/definitions/ShaderParam" @@ -633,6 +670,13 @@ "type": "null" } ] + }, + "border_radius": { + "type": [ + "number", + "null" + ], + "format": "float" } }, "additionalProperties": false @@ -703,7 +747,7 @@ ] }, "width": { - "description": "Width of a component in pixels. Exact behavior might be different based on the parent\ncomponent:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", + "description": "Width of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", "type": [ "number", "null" @@ -711,7 +755,7 @@ "format": "float" }, "height": { - "description": "Height of a component in pixels. Exact behavior might be different based on the parent\ncomponent:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", + "description": "Height of a component in pixels (without a border). Exact behavior might be different\nbased on the parent component:\n- If the parent component is a layout, check sections \"Absolute positioning\" and \"Static\npositioning\" of that component.\n- If the parent component is not a layout, then this field is required.", "type": [ "number", "null" @@ -719,7 +763,7 @@ "format": "float" }, "top": { - "description": "Distance in pixels between this component's top edge and its parent's top edge.\nIf this field is defined, then the component will ignore a layout defined by its parent.", + "description": "Distance in pixels between this component's top edge and its parent's top edge (including a border).\nIf this field is defined, then the component will ignore a layout defined by its parent.", "type": [ "number", "null" @@ -727,7 +771,7 @@ "format": "float" }, "left": { - "description": "Distance in pixels between this component's left edge and its parent's left edge.\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", + "description": "Distance in pixels between this component's left edge and its parent's left edge (including a border).\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", "type": [ "number", "null" @@ -735,7 +779,7 @@ "format": "float" }, "bottom": { - "description": "Distance in pixels between this component's bottom edge and its parent's bottom edge.\nIf this field is defined, this element will be absolutely positioned, instead of being\nlaid out by its parent.", + "description": "Distance in pixels between the bottom edge of this component and the bottom edge of its\nparent (including a border). If this field is defined, this element will be absolutely\npositioned, instead of being laid out by its parent.", "type": [ "number", "null" @@ -768,6 +812,43 @@ "type": "null" } ] + }, + "border_radius": { + "description": "(**default=`0.0`**) Radius of a rounded corner.", + "type": [ + "number", + "null" + ], + "format": "float" + }, + "border_width": { + "description": "(**default=`0.0`**) Border width.", + "type": [ + "number", + "null" + ], + "format": "float" + }, + "border_color_rgba": { + "description": "(**default=`\"#00000000\"`**) Border color in a `\"#RRGGBBAA\"` format.", + "anyOf": [ + { + "$ref": "#/definitions/RGBAColor" + }, + { + "type": "null" + } + ] + }, + "box_shadow": { + "description": "List of box shadows.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/BoxShadow" + } } }, "additionalProperties": false @@ -907,6 +988,43 @@ "RGBAColor": { "type": "string" }, + "BoxShadow": { + "type": "object", + "properties": { + "offset_x": { + "type": [ + "number", + "null" + ], + "format": "float" + }, + "offset_y": { + "type": [ + "number", + "null" + ], + "format": "float" + }, + "color_rgba": { + "anyOf": [ + { + "$ref": "#/definitions/RGBAColor" + }, + { + "type": "null" + } + ] + }, + "blur_radius": { + "type": [ + "number", + "null" + ], + "format": "float" + } + }, + "additionalProperties": false + }, "RendererId": { "type": "string" }, diff --git a/snapshot_tests/rescaler/border_radius.scene.json b/snapshot_tests/rescaler/border_radius.scene.json new file mode 100644 index 000000000..d870231f7 --- /dev/null +++ b/snapshot_tests/rescaler/border_radius.scene.json @@ -0,0 +1,22 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_radius_border_box_shadow.scene.json b/snapshot_tests/rescaler/border_radius_border_box_shadow.scene.json new file mode 100644 index 000000000..669378200 --- /dev/null +++ b/snapshot_tests/rescaler/border_radius_border_box_shadow.scene.json @@ -0,0 +1,32 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_radius_border_box_shadow_rescaled.scene.json b/snapshot_tests/rescaler/border_radius_border_box_shadow_rescaled.scene.json new file mode 100644 index 000000000..0f1084b6d --- /dev/null +++ b/snapshot_tests/rescaler/border_radius_border_box_shadow_rescaled.scene.json @@ -0,0 +1,37 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "width": 600, + "height": 300, + "horizontal_align": "center", + "vertical_align": "center", + "child": { + "type": "rescaler", + "width": 200, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 20, + "offset_y": 20, + "blur_radius": 5, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_radius_box_shadow.scene.json b/snapshot_tests/rescaler/border_radius_box_shadow.scene.json new file mode 100644 index 000000000..e226b108c --- /dev/null +++ b/snapshot_tests/rescaler/border_radius_box_shadow.scene.json @@ -0,0 +1,30 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_radius_box_shadow_fill_input_stream.scene.json b/snapshot_tests/rescaler/border_radius_box_shadow_fill_input_stream.scene.json new file mode 100644 index 000000000..813b30e26 --- /dev/null +++ b/snapshot_tests/rescaler/border_radius_box_shadow_fill_input_stream.scene.json @@ -0,0 +1,33 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "mode": "fill", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_radius_box_shadow_fit_input_stream.scene.json b/snapshot_tests/rescaler/border_radius_box_shadow_fit_input_stream.scene.json new file mode 100644 index 000000000..ff9cc6e93 --- /dev/null +++ b/snapshot_tests/rescaler/border_radius_box_shadow_fit_input_stream.scene.json @@ -0,0 +1,33 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "mode": "fit", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/border_width.scene.json b/snapshot_tests/rescaler/border_width.scene.json new file mode 100644 index 000000000..8705ebd2c --- /dev/null +++ b/snapshot_tests/rescaler/border_width.scene.json @@ -0,0 +1,23 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/box_shadow.scene.json b/snapshot_tests/rescaler/box_shadow.scene.json new file mode 100644 index 000000000..dcfd76a9d --- /dev/null +++ b/snapshot_tests/rescaler/box_shadow.scene.json @@ -0,0 +1,29 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF" + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/nested_border_width_radius.scene.json b/snapshot_tests/rescaler/nested_border_width_radius.scene.json new file mode 100644 index 000000000..342e39a0b --- /dev/null +++ b/snapshot_tests/rescaler/nested_border_width_radius.scene.json @@ -0,0 +1,37 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FF0000FF", + "child": { + "type": "rescaler", + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#00FF00FF", + "child": { + "type": "rescaler", + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#0000FFFF", + "mode": "fill", + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + } + } + ] + } + } +} diff --git a/snapshot_tests/rescaler/nested_border_width_radius_aligned.scene.json b/snapshot_tests/rescaler/nested_border_width_radius_aligned.scene.json new file mode 100644 index 000000000..03b0e49c2 --- /dev/null +++ b/snapshot_tests/rescaler/nested_border_width_radius_aligned.scene.json @@ -0,0 +1,37 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 80, + "border_width": 20, + "border_color_rgba": "#FF0000FF", + "child": { + "type": "rescaler", + "border_radius": 60, + "border_width": 20, + "border_color_rgba": "#00FF00FF", + "child": { + "type": "rescaler", + "border_radius": 40, + "border_width": 20, + "border_color_rgba": "#0000FFFF", + "mode": "fill", + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + } + } + ] + } + } +} diff --git a/snapshot_tests/simple_input_pass_through.scene.json b/snapshot_tests/simple/simple_input_pass_through.scene.json similarity index 100% rename from snapshot_tests/simple_input_pass_through.scene.json rename to snapshot_tests/simple/simple_input_pass_through.scene.json diff --git a/snapshot_tests/text/align_center.scene.json b/snapshot_tests/text/align_center.scene.json index 5223887dd..afbaea49b 100644 --- a/snapshot_tests/text/align_center.scene.json +++ b/snapshot_tests/text/align_center.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "align": "center", "width": 1000, "height": 200 diff --git a/snapshot_tests/text/align_right.scene.json b/snapshot_tests/text/align_right.scene.json index 6fa3e7372..d72b686f5 100644 --- a/snapshot_tests/text/align_right.scene.json +++ b/snapshot_tests/text/align_right.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "align": "right", "width": 1000, "height": 200 diff --git a/snapshot_tests/text/bold_text.scene.json b/snapshot_tests/text/bold_text.scene.json index d699a6c35..8c98f7933 100644 --- a/snapshot_tests/text/bold_text.scene.json +++ b/snapshot_tests/text/bold_text.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "align": "right", "weight": "bold", "width": 1000, diff --git a/snapshot_tests/text/dimensions_fitted.scene.json b/snapshot_tests/text/dimensions_fitted.scene.json index eabb98a38..7dfdb090b 100644 --- a/snapshot_tests/text/dimensions_fitted.scene.json +++ b/snapshot_tests/text/dimensions_fitted.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "background_color_rgba": "#FF0000FF" } ] diff --git a/snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json b/snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json index 3f953ffde..ad911d54e 100644 --- a/snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json +++ b/snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example long text that should be longer that underlaying texture.", "font_size": 30, - "font_family": "Verdana", + "font_family": "Inter", "width": 300 } ] diff --git a/snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json b/snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json index 84dda9749..dd4eca462 100644 --- a/snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json +++ b/snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 30, - "font_family": "Verdana", + "font_family": "Inter", "width": 300 } ] diff --git a/snapshot_tests/text/dimensions_fixed.scene.json b/snapshot_tests/text/dimensions_fixed.scene.json index e448d8427..a9c5daa60 100644 --- a/snapshot_tests/text/dimensions_fixed.scene.json +++ b/snapshot_tests/text/dimensions_fixed.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "width": 1000, "height": 200 } diff --git a/snapshot_tests/text/dimensions_fixed_with_overflow.scene.json b/snapshot_tests/text/dimensions_fixed_with_overflow.scene.json index 5efaf64cd..00895a433 100644 --- a/snapshot_tests/text/dimensions_fixed_with_overflow.scene.json +++ b/snapshot_tests/text/dimensions_fixed_with_overflow.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 120, - "font_family": "Verdana", + "font_family": "Inter", "width": 640, "height": 80 } diff --git a/snapshot_tests/text/red_text_on_blue_background.scene.json b/snapshot_tests/text/red_text_on_blue_background.scene.json index 5f020d705..3ce59d824 100644 --- a/snapshot_tests/text/red_text_on_blue_background.scene.json +++ b/snapshot_tests/text/red_text_on_blue_background.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Example text", "font_size": 50, - "font_family": "Verdana", + "font_family": "Inter", "align": "left", "wrap": "word", "color_rgba": "#FF0000FF", diff --git a/snapshot_tests/text/root_text.scene.json b/snapshot_tests/text/root_text.scene.json index 39f04ee19..ff243b846 100644 --- a/snapshot_tests/text/root_text.scene.json +++ b/snapshot_tests/text/root_text.scene.json @@ -4,7 +4,7 @@ "type": "text", "text": "Example text", "font_size": 100, - "font_family": "Verdana", + "font_family": "Inter", "width": 1000, "height": 200 } diff --git a/snapshot_tests/text/wrap_glyph.scene.json b/snapshot_tests/text/wrap_glyph.scene.json index b38861b65..bbe71ba5b 100644 --- a/snapshot_tests/text/wrap_glyph.scene.json +++ b/snapshot_tests/text/wrap_glyph.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id eros non eros dictum scelerisque. Sed vehicula magna et metus fringilla, nec placerat felis elementum. Nullam tincidunt dui id purus egestas, et pulvinar est facilisis.", "font_size": 50, - "font_family": "Verdana", + "font_family": "Inter", "align": "left", "wrap": "glyph", "width": 1000, diff --git a/snapshot_tests/text/wrap_none.scene.json b/snapshot_tests/text/wrap_none.scene.json index 5455b67f8..56af073cc 100644 --- a/snapshot_tests/text/wrap_none.scene.json +++ b/snapshot_tests/text/wrap_none.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id eros non eros dictum scelerisque. Sed vehicula magna et metus fringilla, nec placerat felis elementum. Nullam tincidunt dui id purus egestas, et pulvinar est facilisis.", "font_size": 50, - "font_family": "Verdana", + "font_family": "Inter", "align": "left", "wrap": "none", "width": 1000, diff --git a/snapshot_tests/text/wrap_word.scene.json b/snapshot_tests/text/wrap_word.scene.json index 4aef48b6c..8b60251c4 100644 --- a/snapshot_tests/text/wrap_word.scene.json +++ b/snapshot_tests/text/wrap_word.scene.json @@ -8,7 +8,7 @@ "type": "text", "text": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum id eros non eros dictum scelerisque. Sed vehicula magna et metus fringilla, nec placerat felis elementum. Nullam tincidunt dui id purus egestas, et pulvinar est facilisis.", "font_size": 50, - "font_family": "Verdana", + "font_family": "Inter", "align": "left", "wrap": "word", "width": 1000, diff --git a/snapshot_tests/view/border_radius.scene.json b/snapshot_tests/view/border_radius.scene.json new file mode 100644 index 000000000..c1ee5d386 --- /dev/null +++ b/snapshot_tests/view/border_radius.scene.json @@ -0,0 +1,19 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50 + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_border_box_shadow.scene.json b/snapshot_tests/view/border_radius_border_box_shadow.scene.json new file mode 100644 index 000000000..93ba6bcd2 --- /dev/null +++ b/snapshot_tests/view/border_radius_border_box_shadow.scene.json @@ -0,0 +1,29 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_border_box_shadow_rescaled.scene.json b/snapshot_tests/view/border_radius_border_box_shadow_rescaled.scene.json new file mode 100644 index 000000000..4849370b2 --- /dev/null +++ b/snapshot_tests/view/border_radius_border_box_shadow_rescaled.scene.json @@ -0,0 +1,34 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "rescaler", + "width": 600, + "height": 300, + "horizontal_align": "center", + "vertical_align": "center", + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF", + "width": 200, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 20, + "offset_y": 20, + "blur_radius": 5, + "color_rgba": "#00FF00FF" + } + ] + } + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_border_box_shadow_rescaled_and_hidden_by_parent.scene.json b/snapshot_tests/view/border_radius_border_box_shadow_rescaled_and_hidden_by_parent.scene.json new file mode 100644 index 000000000..45c66220f --- /dev/null +++ b/snapshot_tests/view/border_radius_border_box_shadow_rescaled_and_hidden_by_parent.scene.json @@ -0,0 +1,41 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "width": 460, + "height": 270, + "children": [ + { + "type": "rescaler", + "width": 600, + "height": 300, + "horizontal_align": "center", + "vertical_align": "center", + "child": { + "type": "view", + "background_color_rgba": "#FF0000FF", + "width": 200, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 20, + "offset_y": 20, + "blur_radius": 5, + "color_rgba": "#00FF00FF" + } + ] + } + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_box_shadow.scene.json b/snapshot_tests/view/border_radius_box_shadow.scene.json new file mode 100644 index 000000000..7529d7fb7 --- /dev/null +++ b/snapshot_tests/view/border_radius_box_shadow.scene.json @@ -0,0 +1,27 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_box_shadow_overflow_fit.scene.json b/snapshot_tests/view/border_radius_box_shadow_overflow_fit.scene.json new file mode 100644 index 000000000..8cc107791 --- /dev/null +++ b/snapshot_tests/view/border_radius_box_shadow_overflow_fit.scene.json @@ -0,0 +1,36 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "overflow": "fit", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_box_shadow_overflow_hidden.scene.json b/snapshot_tests/view/border_radius_box_shadow_overflow_hidden.scene.json new file mode 100644 index 000000000..cc401d7a5 --- /dev/null +++ b/snapshot_tests/view/border_radius_box_shadow_overflow_hidden.scene.json @@ -0,0 +1,35 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_radius_box_shadow_rescaler_input_stream.scene.json b/snapshot_tests/view/border_radius_box_shadow_rescaler_input_stream.scene.json new file mode 100644 index 000000000..3cb05a51a --- /dev/null +++ b/snapshot_tests/view/border_radius_box_shadow_rescaler_input_stream.scene.json @@ -0,0 +1,40 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ], + "children": [ + { + "type": "rescaler", + "mode": "fill", + "vertical_align": "top", + "child": { + "type": "input_stream", + "input_id": "input_1" + } + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/border_width.scene.json b/snapshot_tests/view/border_width.scene.json new file mode 100644 index 000000000..91410189a --- /dev/null +++ b/snapshot_tests/view/border_width.scene.json @@ -0,0 +1,20 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF" + } + ] + } + } +} diff --git a/snapshot_tests/view/box_shadow.scene.json b/snapshot_tests/view/box_shadow.scene.json new file mode 100644 index 000000000..00df6994b --- /dev/null +++ b/snapshot_tests/view/box_shadow.scene.json @@ -0,0 +1,26 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/box_shadow_sibling.scene.json b/snapshot_tests/view/box_shadow_sibling.scene.json new file mode 100644 index 000000000..16e214f56 --- /dev/null +++ b/snapshot_tests/view/box_shadow_sibling.scene.json @@ -0,0 +1,52 @@ +{ + "video": { + "root": { + "type": "view", + "children": [ + { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "overflow": "visible", + "top": 100, + "left": 100, + "width": 400, + "height": 200, + "children": [ + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "box_shadow": [ + { + "offset_x": 0, + "offset_y": 60, + "blur_radius": 30, + "color_rgba": "#FF0000FF" + }, + { + "offset_x": -60, + "offset_y": -30, + "blur_radius": 30, + "color_rgba": "#0000FFFF" + } + ] + }, + { + "type": "view", + "background_color_rgba": "#FF0000FF", + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#0000FFFF" + } + ] + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/nested_border_width_radius.scene.json b/snapshot_tests/view/nested_border_width_radius.scene.json new file mode 100644 index 000000000..d13427f84 --- /dev/null +++ b/snapshot_tests/view/nested_border_width_radius.scene.json @@ -0,0 +1,42 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FF0000FF", + "children": [ + { + "type": "view", + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#00FF00FF", + "children": [ + { + "type": "view", + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#0000FFFF", + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/nested_border_width_radius_aligned.scene.json b/snapshot_tests/view/nested_border_width_radius_aligned.scene.json new file mode 100644 index 000000000..ddf6b7cc2 --- /dev/null +++ b/snapshot_tests/view/nested_border_width_radius_aligned.scene.json @@ -0,0 +1,42 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 80, + "border_width": 20, + "border_color_rgba": "#FF0000FF", + "children": [ + { + "type": "view", + "border_radius": 60, + "border_width": 20, + "border_color_rgba": "#00FF00FF", + "children": [ + { + "type": "view", + "border_radius": 40, + "border_width": 20, + "border_color_rgba": "#0000FFFF", + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/nested_border_width_radius_multi_child.scene.json b/snapshot_tests/view/nested_border_width_radius_multi_child.scene.json new file mode 100644 index 000000000..c8a740c7f --- /dev/null +++ b/snapshot_tests/view/nested_border_width_radius_multi_child.scene.json @@ -0,0 +1,74 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FFFF00FF", + "children": [ + { + "type": "view", + "top": 50, + "left": 50, + "width": 400, + "height": 200, + "border_radius": 50, + "border_width": 10, + "border_color_rgba": "#FF0000FF", + "children": [ + { + "type": "view", + "border_radius": 40, + "border_width": 10, + "border_color_rgba": "#00FF00FF", + "children": [ + { + "type": "view", + "border_radius": 30, + "border_width": 10, + "border_color_rgba": "#0000FFFF", + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + }, + { + "type": "view", + "border_radius": 40, + "border_width": 10, + "border_color_rgba": "#00FF00FF", + "children": [ + { + "type": "view", + "border_radius": 30, + "border_width": 10, + "border_color_rgba": "#0000FFFF", + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + }, + { + "type": "view", + "border_radius": 30, + "border_width": 10, + "border_color_rgba": "#0000FFFF", + "children": [ + { + "type": "input_stream", + "input_id": "input_1" + } + ] + } + ] + } + ] + } + ] + } + } +} diff --git a/snapshot_tests/view/root_border_radius_border_box_shadow.scene.json b/snapshot_tests/view/root_border_radius_border_box_shadow.scene.json new file mode 100644 index 000000000..3e424d513 --- /dev/null +++ b/snapshot_tests/view/root_border_radius_border_box_shadow.scene.json @@ -0,0 +1,19 @@ +{ + "video": { + "root": { + "type": "view", + "background_color_rgba": "#FF0000FF", + "border_radius": 50, + "border_width": 20, + "border_color_rgba": "#FFFFFFFF", + "box_shadow": [ + { + "offset_x": 60, + "offset_y": 30, + "blur_radius": 30, + "color_rgba": "#00FF00FF" + } + ] + } + } +} diff --git a/src/bin/update_snapshots/main.rs b/src/bin/update_snapshots/main.rs deleted file mode 100644 index 5be1e8ae1..000000000 --- a/src/bin/update_snapshots/main.rs +++ /dev/null @@ -1,84 +0,0 @@ -use std::{collections::HashSet, fs, io}; - -#[path = "../../snapshot_tests/tests.rs"] -mod tests; - -#[allow(dead_code)] -#[path = "../../snapshot_tests/utils.rs"] -mod utils; - -#[path = "../../snapshot_tests/test_case.rs"] -mod test_case; - -use tests::snapshot_tests; - -use crate::{ - test_case::TestCaseInstance, - utils::{find_unused_snapshots, snapshots_path}, -}; - -fn main() { - println!("Updating snapshots:"); - tracing_subscriber::fmt().init(); - - let tests: Vec<_> = snapshot_tests(); - let has_only_flag = tests.iter().any(|t| t.only); - let tests: Vec<_> = if has_only_flag { - tests - .into_iter() - .filter(|t| t.only) - .map(TestCaseInstance::new) - .collect() - } else { - tests.into_iter().map(TestCaseInstance::new).collect() - }; - for test in tests.iter() { - for pts in &test.case.timestamps { - let (snapshot, Err(_)) = test.test_snapshots_for_pts(*pts) else { - println!("PASS: \"{}\" (pts: {}ms)", test.case.name, pts.as_millis()); - continue; - }; - - println!( - "UPDATE: \"{}\" (pts: {}ms)", - test.case.name, - pts.as_millis() - ); - - let snapshot_path = snapshot.save_path(); - - if let Err(err) = fs::remove_file(&snapshot_path) { - if err.kind() != io::ErrorKind::NotFound { - panic!("Failed to remove old snapshots: {err}"); - } - } - let parent_folder = snapshot_path.parent().unwrap(); - if !parent_folder.exists() { - fs::create_dir_all(parent_folder).unwrap(); - } - - let width = snapshot.resolution.width - (snapshot.resolution.width % 2); - let height = snapshot.resolution.height - (snapshot.resolution.height % 2); - image::save_buffer( - snapshot_path, - &snapshot.data, - width as u32, - height as u32, - image::ColorType::Rgba8, - ) - .unwrap(); - } - } - if !has_only_flag { - // Check for unused snapshots - let snapshot_paths = tests - .iter() - .flat_map(TestCaseInstance::snapshot_paths) - .collect::>(); - for path in find_unused_snapshots(&snapshot_paths, snapshots_path()) { - println!("Removed unused snapshot {path:?}"); - fs::remove_file(path).unwrap(); - } - } - println!("Update finished"); -} diff --git a/src/config.rs b/src/config.rs index 7035ff010..1869cb65e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,4 +1,10 @@ -use std::{env, path::PathBuf, str::FromStr, time::Duration}; +use std::{ + env, + path::{Path, PathBuf}, + str::FromStr, + sync::Arc, + time::Duration, +}; use compositor_pipeline::queue::{self, QueueOptions}; use compositor_render::{web_renderer::WebRendererInitOptions, Framerate, WgpuFeatures}; @@ -25,6 +31,7 @@ pub struct LoggerConfig { pub ffmpeg_logger_level: FfmpegLogLevel, pub format: LoggerFormat, pub level: String, + pub log_file: Option>, } #[derive(Debug, Copy, Clone)] @@ -182,6 +189,11 @@ fn try_read_config() -> Result { Err(_) => queue::DEFAULT_BUFFER_DURATION, }; + let log_file = match env::var("LIVE_COMPOSITOR_LOG_FILE") { + Ok(path) => Some(Arc::from(PathBuf::from(path))), + Err(_) => None, + }; + let config = Config { instance_id, api_port, @@ -189,6 +201,7 @@ fn try_read_config() -> Result { ffmpeg_logger_level, format: logger_format, level: logger_level, + log_file, }, queue_options: QueueOptions { default_buffer_duration, diff --git a/src/lib.rs b/src/lib.rs index f24d5211f..d0a1c5f43 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,3 +4,6 @@ pub mod middleware; pub mod routes; pub mod server; pub mod state; + +#[cfg(test)] +mod snapshot_tests; diff --git a/src/logger.rs b/src/logger.rs index 69a562414..4f3925209 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,4 +1,16 @@ -use std::{str::FromStr, sync::OnceLock}; +use std::{ + fmt::Debug, + fs::{self, File}, + str::FromStr, + sync::OnceLock, +}; + +use tracing_subscriber::{ + fmt::{self}, + layer::SubscriberExt, + util::SubscriberInitExt, + Layer, Registry, +}; use crate::config::{read_config, LoggerConfig, LoggerFormat}; @@ -58,27 +70,37 @@ extern "C" fn ffmpeg_log_callback( } pub fn init_logger(opts: LoggerConfig) { - let env_filter = tracing_subscriber::EnvFilter::new(opts.level); - match opts.format { - LoggerFormat::Pretty => { - tracing_subscriber::fmt() - .pretty() - .with_env_filter(env_filter) - .init(); - } - LoggerFormat::Json => { - tracing_subscriber::fmt() - .json() - .with_env_filter(env_filter) - .init(); - } - LoggerFormat::Compact => { - tracing_subscriber::fmt() - .compact() - .with_env_filter(env_filter) - .init(); - } + let env_filter = tracing_subscriber::EnvFilter::new(opts.level.clone()); + + let stdout_layer = match opts.format { + LoggerFormat::Pretty => fmt::Layer::default().pretty().boxed(), + LoggerFormat::Json => fmt::Layer::default().json().boxed(), + LoggerFormat::Compact => fmt::Layer::default().compact().boxed(), + }; + + let file_layer = if let Some(log_file) = opts.log_file { + if log_file.exists() { + fs::remove_file(&log_file).unwrap() + }; + fs::create_dir_all(log_file.parent().unwrap()).unwrap(); + let writer = File::create(log_file).unwrap(); + Some(fmt::Layer::default().json().with_writer(writer)) + } else { + None + }; + + match file_layer { + Some(file_layer) => Registry::default() + .with(stdout_layer) + .with(file_layer) + .with(env_filter) + .init(), + None => Registry::default() + .with(stdout_layer) + .with(env_filter) + .init(), } + unsafe { ffmpeg_next::sys::av_log_set_callback(Some(ffmpeg_log_callback)); } diff --git a/src/main.rs b/src/main.rs index c463d9312..dbe1771a3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,9 +7,6 @@ mod routes; mod server; mod state; -#[cfg(test)] -mod snapshot_tests; - fn main() { #[cfg(feature = "web_renderer")] { diff --git a/src/snapshot_tests.rs b/src/snapshot_tests.rs index 632ca90d3..1ead65b80 100644 --- a/src/snapshot_tests.rs +++ b/src/snapshot_tests.rs @@ -1,89 +1,135 @@ -use std::{collections::HashSet, env, fs, path::PathBuf}; - -use self::{ - test_case::{TestCaseError, TestCaseInstance}, - tests::snapshot_tests, - utils::{find_unused_snapshots, snapshots_path}, +use std::{ + collections::HashSet, + fs, + path::{Path, PathBuf}, + time::Duration, }; +use compositor_api::types::UpdateOutputRequest; +use compositor_render::{scene::Component, Resolution}; +use test_case::{TestCase, TestResult, OUTPUT_ID}; +use utils::SNAPSHOTS_DIR_NAME; + +mod input; +mod snapshot; mod test_case; -mod tests; mod utils; -#[test] -fn test_snapshots() { - let tests: Vec = snapshot_tests() - .into_iter() - .map(TestCaseInstance::new) - .collect(); +mod image_tests; +mod rescaler_tests; +mod shader_tests; +mod simple_tests; +mod text_tests; +mod tiles_tests; +mod tiles_transitions_tests; +mod transition_tests; +mod view_tests; +mod yuv_tests; - check_test_names_uniqueness(&tests); +const DEFAULT_RESOLUTION: Resolution = Resolution { + width: 640, + height: 360, +}; - for test in tests.iter() { - eprintln!("Test \"{}\"", test.case.name); - if let Err(err) = test.run() { - handle_error(err); +struct TestRunner { + cases: Vec, + snapshot_dir: PathBuf, +} + +impl TestRunner { + fn new(snapshot_dir: PathBuf) -> Self { + Self { + cases: Vec::new(), + snapshot_dir, } } - // Check for unused snapshots - let snapshot_paths = tests - .iter() - .flat_map(TestCaseInstance::snapshot_paths) - .collect::>(); - let unused_snapshots = find_unused_snapshots(&snapshot_paths, snapshots_path()); - if !unused_snapshots.is_empty() { - panic!("Some snapshots were not used: {unused_snapshots:#?}") + fn add(&mut self, case: TestCase) { + self.cases.push(case) } -} -fn handle_error(err: TestCaseError) { - let TestCaseError::Mismatch { - ref snapshot_from_disk, - ref produced_snapshot, - .. - } = err - else { - panic!("{err}"); - }; - - let failed_snapshot_path = failed_snapshot_path(); - if !failed_snapshot_path.exists() { - fs::create_dir_all(&failed_snapshot_path).unwrap(); + fn run(self) { + check_test_names_uniqueness(&self.cases); + check_unused_snapshots(&self.cases, &self.snapshot_dir); + let has_only = self.cases.iter().any(|test| test.only); + + let mut failed = false; + for test in self.cases.iter() { + if has_only && !test.only { + continue; + } + println!("Test \"{}\"", test.name); + if let TestResult::Failure = test.run() { + failed = true; + } + } + if failed { + panic!("Test failed") + } } - let snapshot_save_path = produced_snapshot.save_path(); - let snapshot_name = snapshot_save_path.file_name().unwrap().to_string_lossy(); - - let width = produced_snapshot.resolution.width - (produced_snapshot.resolution.width % 2); - let height = produced_snapshot.resolution.height - (produced_snapshot.resolution.height % 2); - image::save_buffer( - failed_snapshot_path.join(format!("mismatched_{snapshot_name}")), - &produced_snapshot.data, - width as u32, - height as u32, - image::ColorType::Rgba8, - ) - .unwrap(); - - snapshot_from_disk - .save(failed_snapshot_path.join(format!("original_{snapshot_name}"))) - .unwrap(); - - panic!("{err}"); } -fn failed_snapshot_path() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("failed_snapshot_tests") +fn scene_from_json(scene: &'static str) -> Vec { + let scene: UpdateOutputRequest = serde_json::from_str(scene).unwrap(); + vec![scene.video.unwrap().try_into().unwrap()] +} + +fn scenes_from_json(scenes: &[&'static str]) -> Vec { + scenes + .iter() + .map(|scene| { + let scene: UpdateOutputRequest = serde_json::from_str(scene).unwrap(); + scene.video.unwrap().try_into().unwrap() + }) + .collect() } -fn check_test_names_uniqueness(tests: &[TestCaseInstance]) { +fn check_test_names_uniqueness(tests: &[TestCase]) { let mut test_names = HashSet::new(); for test in tests.iter() { - if !test_names.insert(test.case.name) { + if !test_names.insert(test.name) { panic!( "Multiple snapshots tests with the same name: \"{}\".", - test.case.name + test.name ); } } } + +fn snapshots_path() -> PathBuf { + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(SNAPSHOTS_DIR_NAME) +} + +fn snapshot_save_path(test_name: &str, pts: &Duration) -> PathBuf { + let out_file_name = format!("{}_{}_{}.png", test_name, pts.as_millis(), OUTPUT_ID); + snapshots_path().join(out_file_name) +} + +fn check_unused_snapshots(tests: &[TestCase], snapshot_dir: &Path) { + let existing_snapshots = tests + .iter() + .flat_map(TestCase::snapshot_paths) + .collect::>(); + let mut unused_snapshots = Vec::new(); + for entry in fs::read_dir(snapshot_dir).unwrap() { + let entry = entry.unwrap(); + if !entry.file_name().to_string_lossy().ends_with(".png") { + continue; + } + + if !existing_snapshots.contains(&entry.path()) { + unused_snapshots.push(entry.path()) + } + } + + if !unused_snapshots.is_empty() { + if cfg!(feature = "update_snapshots") { + for snapshot_path in unused_snapshots { + println!("DELETE: Unused snapshot {snapshot_path:?}"); + fs::remove_file(snapshot_path).unwrap(); + } + } else { + panic!("Some snapshots were not used: {unused_snapshots:#?}") + } + } +} diff --git a/src/snapshot_tests/image_tests.rs b/src/snapshot_tests/image_tests.rs new file mode 100644 index 000000000..60360413e --- /dev/null +++ b/src/snapshot_tests/image_tests.rs @@ -0,0 +1,76 @@ +use compositor_render::{ + image::{ImageSource, ImageSpec, ImageType}, + RendererId, RendererSpec, +}; + +use super::{ + input::TestInput, scene_from_json, scenes_from_json, snapshots_path, test_case::TestCase, + TestRunner, +}; + +#[test] +fn image_tests() { + let mut runner = TestRunner::new(snapshots_path().join("image")); + + let image_renderer = ( + RendererId("image_jpeg".into()), + RendererSpec::Image(ImageSpec { + src: ImageSource::Url { + url: "https://www.rust-lang.org/static/images/rust-social.jpg".to_string(), + }, + image_type: ImageType::Jpeg, + }), + ); + + runner.add(TestCase { + name: "image/jpeg_as_root", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/image/jpeg_as_root.scene.json" + )), + renderers: vec![image_renderer.clone()], + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + runner.add(TestCase { + name: "image/jpeg_in_view", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/image/jpeg_in_view.scene.json" + )), + renderers: vec![image_renderer.clone()], + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + runner.add(TestCase { + name: "image/jpeg_in_view_overflow_fit", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/image/jpeg_in_view_overflow_fit.scene.json" + )), + renderers: vec![image_renderer.clone()], + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + runner.add(TestCase { + // Test if removing image from scene works + name: "image/remove_jpeg_as_root", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/image/jpeg_as_root.scene.json"), + include_str!("../../snapshot_tests/view/empty_view.scene.json"), + ]), + renderers: vec![image_renderer.clone()], + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + runner.add(TestCase { + // Test if removing image from scene works + name: "image/remove_jpeg_in_view", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/image/jpeg_in_view.scene.json"), + include_str!("../../snapshot_tests/view/empty_view.scene.json"), + ]), + renderers: vec![image_renderer.clone()], + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + + runner.run() +} diff --git a/src/snapshot_tests/input.rs b/src/snapshot_tests/input.rs new file mode 100644 index 000000000..b01567772 --- /dev/null +++ b/src/snapshot_tests/input.rs @@ -0,0 +1,111 @@ +use compositor_render::{scene::RGBColor, FrameData, Resolution, YuvPlanes}; + +#[derive(Debug, Clone)] +pub(super) struct TestInput { + pub name: String, + pub resolution: Resolution, + pub data: FrameData, +} + +impl TestInput { + const COLOR_VARIANTS: [RGBColor; 17] = [ + // RED, input_0 + RGBColor(255, 0, 0), + // GREEN, input_1 + RGBColor(0, 255, 0), + // YELLOW, input_2 + RGBColor(255, 255, 0), + // MAGENTA, input_3 + RGBColor(255, 0, 255), + // BLUE, input_4 + RGBColor(0, 0, 255), + // CYAN, input_5 + RGBColor(0, 255, 255), + // ORANGE, input_6 + RGBColor(255, 165, 0), + // WHITE, input_7 + RGBColor(255, 255, 255), + // GRAY, input_8 + RGBColor(128, 128, 128), + // LIGHT_RED, input_9 + RGBColor(255, 128, 128), + // LIGHT_BLUE, input_10 + RGBColor(128, 128, 255), + // LIGHT_GREEN, input_11 + RGBColor(128, 255, 128), + // PINK, input_12 + RGBColor(255, 192, 203), + // PURPLE, input_13 + RGBColor(128, 0, 128), + // BROWN, input_14 + RGBColor(165, 42, 42), + // YELLOW_GREEN, input_15 + RGBColor(154, 205, 50), + // LIGHT_YELLOW, input_16 + RGBColor(255, 255, 224), + ]; + + pub fn new(index: usize) -> Self { + Self::new_with_resolution( + index, + Resolution { + width: 640, + height: 360, + }, + ) + } + + pub fn new_with_resolution(index: usize, resolution: Resolution) -> Self { + let color = Self::COLOR_VARIANTS[index].to_yuv(); + let mut y_plane = vec![0; resolution.width * resolution.height]; + let mut u_plane = vec![0; (resolution.width * resolution.height) / 4]; + let mut v_plane = vec![0; (resolution.width * resolution.height) / 4]; + + let yuv_color = |x: usize, y: usize| { + const BORDER_SIZE: usize = 18; + const GRID_SIZE: usize = 72; + + let is_border_in_x = + x <= BORDER_SIZE || (x <= resolution.width && x >= resolution.width - BORDER_SIZE); + let is_border_in_y: bool = y <= BORDER_SIZE + || (y <= resolution.height && y >= resolution.height - BORDER_SIZE); + let is_on_grid = (x / GRID_SIZE + y / GRID_SIZE) % 2 == 0; + + let mut y = color.0; + if is_border_in_x || is_border_in_y || is_on_grid { + y -= 0.2; + } + + (y.clamp(0.0, 1.0), color.1, color.2) + }; + + for x_coord in 0..resolution.width { + for y_coord in 0..resolution.height { + let (y, u, v) = yuv_color(x_coord, y_coord); + if x_coord % 2 == 0 && y_coord % 2 == 0 { + let (_, u2, v2) = yuv_color(x_coord + 1, y_coord); + let (_, u3, v3) = yuv_color(x_coord, y_coord + 1); + let (_, u4, v4) = yuv_color(x_coord + 1, y_coord + 1); + + let coord = (y_coord / 2) * (resolution.width / 2) + (x_coord / 2); + u_plane[coord] = ((u + u2 + u3 + u4) * 64.0) as u8; + v_plane[coord] = ((v + v2 + v3 + v4) * 64.0) as u8; + } + + y_plane[y_coord * resolution.width + x_coord] = (y * 255.0) as u8; + } + } + + let data = FrameData::PlanarYuv420(YuvPlanes { + y_plane: y_plane.into(), + u_plane: u_plane.into(), + v_plane: v_plane.into(), + }); + + Self { + name: format!("input_{index}"), + resolution, + data, + } + } +} diff --git a/src/snapshot_tests/rescaler_tests.rs b/src/snapshot_tests/rescaler_tests.rs new file mode 100644 index 000000000..a14b7d348 --- /dev/null +++ b/src/snapshot_tests/rescaler_tests.rs @@ -0,0 +1,250 @@ +use compositor_render::Resolution; + +use super::{ + input::TestInput, scene_from_json, snapshots_path, test_case::TestCase, TestRunner, + DEFAULT_RESOLUTION, +}; + +#[test] +fn rescaler_tests() { + let mut runner = TestRunner::new(snapshots_path().join("rescaler")); + let default = TestCase { + inputs: vec![TestInput::new(1)], + ..Default::default() + }; + + let higher_than_default_resolution = Resolution { + width: DEFAULT_RESOLUTION.width, + height: DEFAULT_RESOLUTION.height + 100, + }; + let lower_than_default_resolution = Resolution { + width: DEFAULT_RESOLUTION.width, + height: DEFAULT_RESOLUTION.height - 100, + }; + let portrait_resolution = Resolution { + width: 360, + height: 640, + }; + let higher_than_default = TestInput::new_with_resolution(1, higher_than_default_resolution); + let lower_than_default = TestInput::new_with_resolution(1, lower_than_default_resolution); + let portrait = TestInput::new_with_resolution(1, portrait_resolution); + + runner.add(TestCase { + name: "rescaler/fit_view_with_known_height", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_view_with_known_height.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_view_with_known_width", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_view_with_known_width.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_view_with_unknown_width_and_height", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_view_with_unknown_width_and_height.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_inverted_aspect_ratio_align_top_left", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream_align_top_left.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_inverted_aspect_ratio_align_bottom_right", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream_align_bottom_right.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_lower_aspect_ratio_align_bottom_right", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream_align_bottom_right.scene.json" + )), + inputs: vec![lower_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_lower_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream.scene.json" + )), + inputs: vec![lower_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_higher_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream.scene.json" + )), + inputs: vec![higher_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_inverted_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fill_input_stream_matching_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fill_input_stream.scene.json" + )), + inputs: vec![TestInput::new(1)], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_lower_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream.scene.json" + )), + inputs: vec![lower_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_higher_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream.scene.json" + )), + inputs: vec![higher_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_higher_aspect_ratio_small_resolution", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream.scene.json" + )), + inputs: vec![TestInput::new_with_resolution( + 1, + Resolution { + width: higher_than_default_resolution.width / 10, + height: higher_than_default_resolution.height / 10, + }, + )], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_inverted_aspect_ratio_align_top_left", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream_align_top_left.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_inverted_aspect_ratio_align_bottom_right", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream_align_bottom_right.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_lower_aspect_ratio_align_bottom_right", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream_align_bottom_right.scene.json" + )), + inputs: vec![lower_than_default.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_inverted_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream.scene.json" + )), + inputs: vec![portrait.clone()], + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/fit_input_stream_matching_aspect_ratio", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/fit_input_stream.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_radius", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_width", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_width.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_radius_border_box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius_border_box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_radius_box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius_box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_radius_box_shadow_fit_input_stream", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius_box_shadow_fit_input_stream.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/border_radius_box_shadow_fill_input_stream", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius_box_shadow_fill_input_stream.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/nested_border_width_radius", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/nested_border_width_radius.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "rescaler/nested_border_width_radius_aligned", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/nested_border_width_radius_aligned.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + // it is supposed to be cut off because of the rescaler that wraps it + name: "rescaler/border_radius_border_box_shadow_rescaled", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/rescaler/border_radius_border_box_shadow_rescaled.scene.json" + )), + ..default.clone() + }); + runner.run() +} diff --git a/src/snapshot_tests/shader_tests.rs b/src/snapshot_tests/shader_tests.rs new file mode 100644 index 000000000..126bce552 --- /dev/null +++ b/src/snapshot_tests/shader_tests.rs @@ -0,0 +1,262 @@ +use std::time::Duration; + +use compositor_render::{ + scene::{ + Component, InputStreamComponent, ShaderComponent, ShaderParam, ShaderParamStructField, + }, + shader::ShaderSpec, + InputId, RendererId, RendererSpec, +}; + +use super::DEFAULT_RESOLUTION; + +use super::{input::TestInput, scene_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn shader_tests() { + let mut runner = TestRunner::new(snapshots_path().join("shader")); + + let input1 = TestInput::new(1); + let input2 = TestInput::new(2); + let input3 = TestInput::new(3); + let input4 = TestInput::new(4); + let input5 = TestInput::new(5); + + let plane_id_shader = ( + RendererId("base_params_plane_id".into()), + RendererSpec::Shader(ShaderSpec { + source: include_str!("../../snapshot_tests/shader/layout_planes.wgsl").into(), + }), + ); + + let time_shader = ( + RendererId("base_params_time".into()), + RendererSpec::Shader(ShaderSpec { + source: include_str!("../../snapshot_tests/shader/fade_to_ball.wgsl").into(), + }), + ); + + let texture_count_shader = ( + RendererId("base_params_texture_count".into()), + RendererSpec::Shader(ShaderSpec { + source: include_str!( + "../../snapshot_tests/shader/color_output_with_texture_count.wgsl" + ) + .into(), + }), + ); + + let output_resolution_shader = ( + RendererId("base_params_output_resolution".into()), + RendererSpec::Shader(ShaderSpec { + source: include_str!("../../snapshot_tests/shader/red_border.wgsl").into(), + }), + ); + + runner.add(TestCase { + name: "shader/base_params_plane_id_no_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_plane_id_no_inputs.scene.json" + )), + renderers: vec![plane_id_shader.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_plane_id_5_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_plane_id_5_inputs.scene.json" + )), + renderers: vec![plane_id_shader.clone()], + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + input5.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_time", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_time.scene.json" + )), + renderers: vec![time_shader.clone()], + inputs: vec![input1.clone()], + timestamps: vec![ + Duration::from_secs(0), + Duration::from_secs(1), + Duration::from_secs(2), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_output_resolution", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_output_resolution.scene.json" + )), + renderers: vec![output_resolution_shader.clone()], + inputs: vec![input1.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_texture_count_no_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_texture_count_no_inputs.scene.json" + )), + renderers: vec![texture_count_shader.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_texture_count_1_input", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_texture_count_1_input.scene.json" + )), + renderers: vec![texture_count_shader.clone()], + inputs: vec![input1.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "shader/base_params_texture_count_2_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/shader/base_params_texture_count_2_inputs.scene.json" + )), + renderers: vec![texture_count_shader.clone()], + inputs: vec![input1.clone(), input2.clone()], + ..Default::default() + }); + + user_params_snapshot_tests(&mut runner); + + runner.run() +} + +fn user_params_snapshot_tests(runner: &mut TestRunner) { + struct CircleLayout { + pub left_px: u32, + pub top_px: u32, + pub width_px: u32, + pub height_px: u32, + /// RGBA 0.0 - 1.0 range + pub background_color: [f32; 4], + } + + impl CircleLayout { + pub fn shader_param(&self) -> ShaderParam { + ShaderParam::Struct(vec![ + ShaderParamStructField { + field_name: "left_px".to_string(), + value: ShaderParam::U32(self.left_px), + }, + ShaderParamStructField { + field_name: "top_px".to_string(), + value: ShaderParam::U32(self.top_px), + }, + ShaderParamStructField { + field_name: "width_px".to_string(), + value: ShaderParam::U32(self.width_px), + }, + ShaderParamStructField { + field_name: "height_px".to_string(), + value: ShaderParam::U32(self.height_px), + }, + ShaderParamStructField { + field_name: "background_color".to_string(), + value: ShaderParam::List(vec![ + ShaderParam::F32(self.background_color[0]), + ShaderParam::F32(self.background_color[1]), + ShaderParam::F32(self.background_color[2]), + ShaderParam::F32(self.background_color[3]), + ]), + }, + ]) + } + } + + let input1 = TestInput::new(1); + let input2 = TestInput::new(2); + let input3 = TestInput::new(3); + let input4 = TestInput::new(4); + + const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; + const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0]; + const BLUE: [f32; 4] = [0.0, 0.0, 1.0, 1.0]; + const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; + + let shader_id = RendererId("user_params_circle_layout".into()); + + let layout1 = CircleLayout { + left_px: 0, + top_px: 0, + width_px: (DEFAULT_RESOLUTION.width / 2) as u32, + height_px: (DEFAULT_RESOLUTION.height / 2) as u32, + background_color: RED, + }; + + let layout2 = CircleLayout { + left_px: (DEFAULT_RESOLUTION.width / 2) as u32, + top_px: 0, + width_px: (DEFAULT_RESOLUTION.width / 2) as u32, + height_px: (DEFAULT_RESOLUTION.height / 2) as u32, + background_color: GREEN, + }; + + let layout3 = CircleLayout { + left_px: 0, + top_px: (DEFAULT_RESOLUTION.height / 2) as u32, + width_px: (DEFAULT_RESOLUTION.width / 2) as u32, + height_px: (DEFAULT_RESOLUTION.height / 2) as u32, + background_color: BLUE, + }; + + let layout4 = CircleLayout { + left_px: (DEFAULT_RESOLUTION.width / 2) as u32, + top_px: (DEFAULT_RESOLUTION.height / 2) as u32, + width_px: (DEFAULT_RESOLUTION.width / 2) as u32, + height_px: (DEFAULT_RESOLUTION.height / 2) as u32, + background_color: WHITE, + }; + + let circle_layout_scene = Component::Shader(ShaderComponent { + id: None, + shader_id: shader_id.clone(), + shader_param: Some(ShaderParam::List(vec![ + layout1.shader_param(), + layout2.shader_param(), + layout3.shader_param(), + layout4.shader_param(), + ])), + size: DEFAULT_RESOLUTION.into(), + children: vec![ + Component::InputStream(InputStreamComponent { + id: None, + input_id: InputId(input1.name.clone().into()), + }), + Component::InputStream(InputStreamComponent { + id: None, + input_id: InputId(input2.name.clone().into()), + }), + Component::InputStream(InputStreamComponent { + id: None, + input_id: InputId(input3.name.clone().into()), + }), + Component::InputStream(InputStreamComponent { + id: None, + input_id: InputId(input4.name.clone().into()), + }), + ], + }); + + runner.add(TestCase { + name: "shader/user_params_circle_layout", + scene_updates: vec![circle_layout_scene], + renderers: vec![( + shader_id.clone(), + RendererSpec::Shader(ShaderSpec { + source: include_str!("../../snapshot_tests/shader/circle_layout.wgsl").into(), + }), + )], + inputs: vec![input1, input2, input3, input4], + ..Default::default() + }); +} diff --git a/src/snapshot_tests/simple_tests.rs b/src/snapshot_tests/simple_tests.rs new file mode 100644 index 000000000..9cbd63103 --- /dev/null +++ b/src/snapshot_tests/simple_tests.rs @@ -0,0 +1,17 @@ +use super::{input::TestInput, scene_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn simple_tests() { + let mut runner = TestRunner::new(snapshots_path().join("simple")); + + runner.add(TestCase { + name: "simple/simple_input_pass_through", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/simple/simple_input_pass_through.scene.json" + )), + inputs: vec![TestInput::new(1)], + ..Default::default() + }); + + runner.run() +} diff --git a/src/snapshot_tests/snapshot.rs b/src/snapshot_tests/snapshot.rs new file mode 100644 index 000000000..395e63617 --- /dev/null +++ b/src/snapshot_tests/snapshot.rs @@ -0,0 +1,90 @@ +use std::{ + fs::{self, create_dir_all}, + path::PathBuf, + time::Duration, +}; + +use compositor_render::Resolution; + +use super::snapshot_save_path; + +#[derive(Debug, Clone)] +pub(super) struct Snapshot { + pub test_name: String, + pub pts: Duration, + pub resolution: Resolution, + pub data: Vec, +} + +impl Snapshot { + pub(super) fn save_path(&self) -> PathBuf { + snapshot_save_path(&self.test_name, &self.pts) + } + + pub(super) fn diff_with_saved(&self) -> f32 { + let save_path = self.save_path(); + if !save_path.exists() { + return 1000.0; + } + let old_snapshot = image::open(save_path).unwrap().to_rgba8(); + snapshots_diff(&old_snapshot, &self.data) + } + + pub(super) fn update_on_disk(&self) { + let width = self.resolution.width - (self.resolution.width % 2); + let height = self.resolution.height - (self.resolution.height % 2); + let save_path = self.save_path(); + create_dir_all(save_path.parent().unwrap()).unwrap(); + image::save_buffer( + save_path, + &self.data, + width as u32, + height as u32, + image::ColorType::Rgba8, + ) + .unwrap(); + } + + pub(super) fn write_as_failed_snapshot(&self) { + let failed_snapshot_path = + PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("failed_snapshot_tests"); + create_dir_all(&failed_snapshot_path).unwrap(); + + let snapshot_name = self + .save_path() + .file_name() + .unwrap() + .to_string_lossy() + .to_string(); + + let width = self.resolution.width - (self.resolution.width % 2); + let height = self.resolution.height - (self.resolution.height % 2); + image::save_buffer( + failed_snapshot_path.join(format!("actual_{snapshot_name}")), + &self.data, + width as u32, + height as u32, + image::ColorType::Rgba8, + ) + .unwrap(); + + fs::copy( + self.save_path(), + failed_snapshot_path.join(format!("expected_{snapshot_name}")), + ) + .unwrap(); + } +} + +fn snapshots_diff(old_snapshot: &[u8], new_snapshot: &[u8]) -> f32 { + if old_snapshot.len() != new_snapshot.len() { + return 10000.0; + } + let square_error: f32 = old_snapshot + .iter() + .zip(new_snapshot) + .map(|(a, b)| (*a as i32 - *b as i32).pow(2) as f32) + .sum(); + + square_error / old_snapshot.len() as f32 +} diff --git a/src/snapshot_tests/test_case.rs b/src/snapshot_tests/test_case.rs index 479b81b04..fbef84ba2 100644 --- a/src/snapshot_tests/test_case.rs +++ b/src/snapshot_tests/test_case.rs @@ -1,31 +1,31 @@ -use std::{fmt::Display, path::PathBuf, sync::Arc, time::Duration}; +use std::{path::PathBuf, sync::Arc, time::Duration}; -use super::utils::{create_renderer, frame_to_rgba, snaphot_save_path, snapshots_diff}; +use super::{ + input::TestInput, + snapshot::Snapshot, + snapshot_save_path, + utils::{create_renderer, frame_to_rgba}, +}; use anyhow::Result; -use compositor_api::types::{self}; use compositor_render::{ - scene::RGBColor, Frame, FrameData, FrameSet, InputId, OutputFrameFormat, OutputId, Renderer, - RendererId, RendererSpec, Resolution, YuvPlanes, + scene::Component, Frame, FrameSet, InputId, OutputFrameFormat, OutputId, Renderer, RendererId, + RendererSpec, Resolution, }; -use image::ImageBuffer; pub(super) const OUTPUT_ID: &str = "output_1"; -pub struct TestCase { +#[derive(Debug, Clone)] +pub(super) struct TestCase { pub name: &'static str, pub inputs: Vec, pub renderers: Vec<(RendererId, RendererSpec)>, pub timestamps: Vec, - pub scene_updates: Updates, - #[allow(dead_code)] + pub scene_updates: Vec, pub only: bool, pub allowed_error: f32, -} - -pub enum Updates { - Scene(&'static str, Resolution), - Scenes(Vec<(&'static str, Resolution)>), + pub resolution: Resolution, + pub output_format: OutputFrameFormat, } impl Default for TestCase { @@ -35,116 +35,102 @@ impl Default for TestCase { inputs: Vec::new(), renderers: Vec::new(), timestamps: vec![Duration::from_secs(0)], - scene_updates: Updates::Scenes(vec![]), + scene_updates: vec![], only: false, - allowed_error: 20.0, + allowed_error: 1.0, + resolution: Resolution { + width: 640, + height: 360, + }, + output_format: OutputFrameFormat::PlanarYuv420Bytes, } } } -pub struct TestCaseInstance { - pub case: TestCase, - pub renderer: Renderer, +pub(super) enum TestResult { + Success, + Failure, } -impl TestCaseInstance { - pub fn new(test_case: TestCase) -> TestCaseInstance { - if test_case.name.is_empty() { - panic!("Snapshot test name has to be provided"); - } - +impl TestCase { + pub(super) fn renderer(&self) -> Renderer { let mut renderer = create_renderer(); - for (id, spec) in test_case.renderers.iter() { + for (id, spec) in self.renderers.iter() { renderer .register_renderer(id.clone(), spec.clone()) .unwrap(); } - for (index, _) in test_case.inputs.iter().enumerate() { + for (index, _) in self.inputs.iter().enumerate() { renderer.register_input(InputId(format!("input_{}", index + 1).into())) } - let outputs = match test_case.scene_updates { - Updates::Scene(scene, resolution) => vec![(scene, resolution)], - Updates::Scenes(ref scenes) => scenes.clone(), - }; - - for (update_str, resolution) in outputs { - let scene: types::UpdateOutputRequest = serde_json::from_str(update_str).unwrap(); - if let Some(root) = scene.video { - renderer - .update_scene( - OutputId(OUTPUT_ID.into()), - resolution, - OutputFrameFormat::PlanarYuv420Bytes, - root.try_into().unwrap(), - ) - .unwrap(); - } + for update in &self.scene_updates { + renderer + .update_scene( + OutputId(OUTPUT_ID.into()), + self.resolution, + self.output_format, + update.clone(), + ) + .unwrap(); } - TestCaseInstance { - case: test_case, - renderer, - } + renderer } - #[allow(dead_code)] - pub fn run(&self) -> Result<(), TestCaseError> { - for pts in self.case.timestamps.iter() { - let (_, test_result) = self.test_snapshots_for_pts(*pts); - test_result?; + pub(super) fn run(&self) -> TestResult { + if self.name.is_empty() { + panic!("Snapshot test name has to be provided"); } - Ok(()) - } + let mut renderer = self.renderer(); + let mut result = TestResult::Success; - pub fn test_snapshots_for_pts(&self, pts: Duration) -> (Snapshot, Result<(), TestCaseError>) { - let snapshot = self.snapshot_for_pts(pts).unwrap(); - - let save_path = snapshot.save_path(); - if !save_path.exists() { - return ( - snapshot.clone(), - Err(TestCaseError::SnapshotNotFound(snapshot.clone())), - ); + for pts in self.timestamps.iter().copied() { + if let TestResult::Failure = self.test_snapshots_for_pts(&mut renderer, pts) { + result = TestResult::Failure; + } } + result + } - let snapshot_from_disk = image::open(&save_path).unwrap().to_rgba8(); - let snapshots_diff = snapshots_diff(&snapshot_from_disk, &snapshot.data); - if snapshots_diff > self.case.allowed_error { - return ( - snapshot.clone(), - Err(TestCaseError::Mismatch { - snapshot_from_disk: snapshot_from_disk.into(), - produced_snapshot: snapshot.clone(), - diff: snapshots_diff, - }), - ); - } + fn test_snapshots_for_pts(&self, renderer: &mut Renderer, pts: Duration) -> TestResult { + let snapshot = self.snapshot_for_pts(renderer, pts).unwrap(); + let snapshots_diff = snapshot.diff_with_saved(); if snapshots_diff > 0.0 { println!( "Snapshot error in range (allowed: {}, current: {})", - self.case.allowed_error, snapshots_diff + self.allowed_error, snapshots_diff ); } - - (snapshot, Ok(())) - } - - #[allow(dead_code)] - pub fn snapshot_paths(&self) -> Vec { - let mut paths = Vec::new(); - for pts in self.case.timestamps.iter() { - paths.push(snaphot_save_path(self.case.name, pts)); + if snapshots_diff > self.allowed_error { + if cfg!(feature = "update_snapshots") { + println!("UPDATE: \"{}\" (pts: {}ms)", self.name, pts.as_millis(),); + snapshot.update_on_disk(); + } else { + println!("FAILED: \"{}\" (pts: {}ms)", self.name, pts.as_millis(),); + snapshot.write_as_failed_snapshot(); + return TestResult::Failure; + } } + TestResult::Success + } - paths + pub(super) fn snapshot_paths(&self) -> Vec { + self.timestamps + .iter() + .map(|pts| snapshot_save_path(self.name, pts)) + .collect() } - pub fn snapshot_for_pts(&self, pts: Duration) -> Result { + pub(super) fn snapshot_for_pts( + &self, + renderer: &mut Renderer, + pts: Duration, + ) -> Result { let mut frame_set = FrameSet::new(pts); - for input in self.case.inputs.iter() { + for input in self.inputs.iter() { let input_id = InputId::from(Arc::from(input.name.clone())); let frame = Frame { data: input.data.clone(), @@ -154,178 +140,15 @@ impl TestCaseInstance { frame_set.frames.insert(input_id, frame); } - let outputs = self.renderer.render(frame_set)?; + let outputs = renderer.render(frame_set)?; let output_frame = outputs.frames.get(&OutputId(OUTPUT_ID.into())).unwrap(); let new_snapshot = frame_to_rgba(output_frame); Ok(Snapshot { - test_name: self.case.name.to_owned(), + test_name: self.name.to_owned(), pts, resolution: output_frame.resolution, data: new_snapshot, }) } } - -#[derive(Debug, Clone)] -pub struct TestInput { - pub name: String, - pub resolution: Resolution, - pub data: FrameData, -} - -impl TestInput { - const COLOR_VARIANTS: [RGBColor; 17] = [ - // RED, input_0 - RGBColor(255, 0, 0), - // GREEN, input_1 - RGBColor(0, 255, 0), - // YELLOW, input_2 - RGBColor(255, 255, 0), - // MAGENTA, input_3 - RGBColor(255, 0, 255), - // BLUE, input_4 - RGBColor(0, 0, 255), - // CYAN, input_5 - RGBColor(0, 255, 255), - // ORANGE, input_6 - RGBColor(255, 165, 0), - // WHITE, input_7 - RGBColor(255, 255, 255), - // GRAY, input_8 - RGBColor(128, 128, 128), - // LIGHT_RED, input_9 - RGBColor(255, 128, 128), - // LIGHT_BLUE, input_10 - RGBColor(128, 128, 255), - // LIGHT_GREEN, input_11 - RGBColor(128, 255, 128), - // PINK, input_12 - RGBColor(255, 192, 203), - // PURPLE, input_13 - RGBColor(128, 0, 128), - // BROWN, input_14 - RGBColor(165, 42, 42), - // YELLOW_GREEN, input_15 - RGBColor(154, 205, 50), - // LIGHT_YELLOW, input_16 - RGBColor(255, 255, 224), - ]; - - pub fn new(index: usize) -> Self { - Self::new_with_resolution( - index, - Resolution { - width: 640, - height: 360, - }, - ) - } - - pub fn new_with_resolution(index: usize, resolution: Resolution) -> Self { - let color = Self::COLOR_VARIANTS[index].to_yuv(); - let mut y_plane = vec![0; resolution.width * resolution.height]; - let mut u_plane = vec![0; (resolution.width * resolution.height) / 4]; - let mut v_plane = vec![0; (resolution.width * resolution.height) / 4]; - - let yuv_color = |x: usize, y: usize| { - const BORDER_SIZE: usize = 18; - const GRID_SIZE: usize = 72; - - let is_border_in_x = - x <= BORDER_SIZE || (x <= resolution.width && x >= resolution.width - BORDER_SIZE); - let is_border_in_y: bool = y <= BORDER_SIZE - || (y <= resolution.height && y >= resolution.height - BORDER_SIZE); - let is_on_grid = (x / GRID_SIZE + y / GRID_SIZE) % 2 == 0; - - let mut y = color.0; - if is_border_in_x || is_border_in_y || is_on_grid { - y -= 0.2; - } - - (y.clamp(0.0, 1.0), color.1, color.2) - }; - - for x_coord in 0..resolution.width { - for y_coord in 0..resolution.height { - let (y, u, v) = yuv_color(x_coord, y_coord); - if x_coord % 2 == 0 && y_coord % 2 == 0 { - let (_, u2, v2) = yuv_color(x_coord + 1, y_coord); - let (_, u3, v3) = yuv_color(x_coord, y_coord + 1); - let (_, u4, v4) = yuv_color(x_coord + 1, y_coord + 1); - - let coord = (y_coord / 2) * (resolution.width / 2) + (x_coord / 2); - u_plane[coord] = ((u + u2 + u3 + u4) * 64.0) as u8; - v_plane[coord] = ((v + v2 + v3 + v4) * 64.0) as u8; - } - - y_plane[y_coord * resolution.width + x_coord] = (y * 255.0) as u8; - } - } - - let data = FrameData::PlanarYuv420(YuvPlanes { - y_plane: y_plane.into(), - u_plane: u_plane.into(), - v_plane: v_plane.into(), - }); - - Self { - name: format!("input_{index}"), - resolution, - data, - } - } -} - -#[derive(Debug, Clone)] -pub struct Snapshot { - pub test_name: String, - pub pts: Duration, - pub resolution: Resolution, - pub data: Vec, -} - -impl Snapshot { - pub fn save_path(&self) -> PathBuf { - snaphot_save_path(&self.test_name, &self.pts) - } -} - -#[derive(Debug)] -pub enum TestCaseError { - SnapshotNotFound(Snapshot), - Mismatch { - #[allow(dead_code)] - snapshot_from_disk: Box, Vec>>, - produced_snapshot: Snapshot, - diff: f32, - }, -} - -impl std::error::Error for TestCaseError {} - -impl Display for TestCaseError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let err_msg = match self { - TestCaseError::SnapshotNotFound(Snapshot { test_name, pts, .. }) => format!( - "FAILED: \"{}\", PTS({}). Snapshot file not found. Generate snapshots first", - test_name, - pts.as_secs() - ), - TestCaseError::Mismatch { - produced_snapshot: Snapshot { test_name, pts, .. }, - diff, - .. - } => { - format!( - "FAILED: \"{}\", PTS({}). Snapshots are different error={}", - test_name, - pts.as_secs_f32(), - diff, - ) - } - }; - - f.write_str(&err_msg) - } -} diff --git a/src/snapshot_tests/tests.rs b/src/snapshot_tests/tests.rs deleted file mode 100644 index 3c0a6a6b5..000000000 --- a/src/snapshot_tests/tests.rs +++ /dev/null @@ -1,1582 +0,0 @@ -use std::time::Duration; - -use compositor_render::{ - image::{ImageSource, ImageSpec, ImageType}, - shader::ShaderSpec, - RendererId, RendererSpec, Resolution, -}; -use serde_json::{json, Value}; - -use super::test_case::{TestCase, TestInput, Updates}; - -const DEFAULT_RESOLUTION: Resolution = Resolution { - width: 640, - height: 360, -}; - -pub fn snapshot_tests() -> Vec { - let mut tests = Vec::new(); - tests.append(&mut base_snapshot_tests()); - tests.append(&mut view_snapshot_tests()); - tests.append(&mut transition_snapshot_tests()); - tests.append(&mut image_snapshot_tests()); - tests.append(&mut text_snapshot_tests()); - tests.append(&mut tiles_snapshot_tests()); - tests.append(&mut rescaler_snapshot_tests()); - tests.append(&mut shader_snapshot_tests()); - tests -} - -fn shader_snapshot_tests() -> Vec { - let mut base_params_snapshot_tests = shader_base_params_snapshot_tests(); - let mut user_params_snapshot_tests = shader_user_params_snapshot_tests(); - - base_params_snapshot_tests.append(&mut user_params_snapshot_tests); - base_params_snapshot_tests -} - -fn shader_user_params_snapshot_tests() -> Vec { - struct CircleLayout { - pub left_px: u32, - pub top_px: u32, - pub width_px: u32, - pub height_px: u32, - /// RGBA 0.0 - 1.0 range - pub background_color: [f32; 4], - } - - impl CircleLayout { - pub fn shader_param(&self) -> Value { - let background_color_params: Vec = self - .background_color - .iter() - .map(|val| { - { - json!({ - "type": "f32", - "value": val - }) - } - }) - .collect(); - - json!({ - "type": "struct", - "value": [ - { - "field_name": "left_px", - "type": "u32", - "value": self.left_px - }, - { - "field_name": "top_px", - "type": "u32", - "value": self.top_px - }, - { - "field_name": "width_px", - "type": "u32", - "value": self.width_px - }, - { - "field_name": "height_px", - "type": "u32", - "value": self.height_px - }, - { - "field_name": "background_color", - "type": "list", - "value": background_color_params - }, - ] - }) - } - } - - let input1 = TestInput::new(1); - let input2 = TestInput::new(2); - let input3 = TestInput::new(3); - let input4 = TestInput::new(4); - - const RED: [f32; 4] = [1.0, 0.0, 0.0, 1.0]; - const GREEN: [f32; 4] = [0.0, 1.0, 0.0, 1.0]; - const BLUE: [f32; 4] = [0.0, 0.0, 1.0, 1.0]; - const WHITE: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; - - let circle_layout_shader = ( - RendererId("user_params_circle_layout".into()), - RendererSpec::Shader(ShaderSpec { - source: include_str!("../../snapshot_tests/shader/circle_layout.wgsl").into(), - }), - ); - - let layout1 = CircleLayout { - left_px: 0, - top_px: 0, - width_px: (DEFAULT_RESOLUTION.width / 2) as u32, - height_px: (DEFAULT_RESOLUTION.height / 2) as u32, - background_color: RED, - }; - - let layout2 = CircleLayout { - left_px: (DEFAULT_RESOLUTION.width / 2) as u32, - top_px: 0, - width_px: (DEFAULT_RESOLUTION.width / 2) as u32, - height_px: (DEFAULT_RESOLUTION.height / 2) as u32, - background_color: GREEN, - }; - - let layout3 = CircleLayout { - left_px: 0, - top_px: (DEFAULT_RESOLUTION.height / 2) as u32, - width_px: (DEFAULT_RESOLUTION.width / 2) as u32, - height_px: (DEFAULT_RESOLUTION.height / 2) as u32, - background_color: BLUE, - }; - - let layout4 = CircleLayout { - left_px: (DEFAULT_RESOLUTION.width / 2) as u32, - top_px: (DEFAULT_RESOLUTION.height / 2) as u32, - width_px: (DEFAULT_RESOLUTION.width / 2) as u32, - height_px: (DEFAULT_RESOLUTION.height / 2) as u32, - background_color: WHITE, - }; - - let shader_param = json!({ - "type": "list", - "value": [ - layout1.shader_param(), - layout2.shader_param(), - layout3.shader_param(), - layout4.shader_param(), - ] - }); - - let inputs = Vec::from([input1, input2, input3, input4]); - - let children: Vec = inputs - .iter() - .map(|input| { - json!({ - "type": "input_stream", - "input_id": input.name - }) - }) - .collect(); - - let circle_layout_scene = Box::new( - json!({ - "video": { - "root": { - "type": "shader", - "shader_id": "user_params_circle_layout", - "resolution": { - "width": DEFAULT_RESOLUTION.width, - "height": DEFAULT_RESOLUTION.height - }, - "shader_param": shader_param, - "children": children, - } - } - }) - .to_string(), - ); - - Vec::from([TestCase { - name: "shader/user_params_circle_layout", - scene_updates: Updates::Scene(circle_layout_scene.leak(), DEFAULT_RESOLUTION), - renderers: vec![circle_layout_shader], - inputs, - ..Default::default() - }]) -} - -fn shader_base_params_snapshot_tests() -> Vec { - let input1 = TestInput::new(1); - let input2 = TestInput::new(2); - let input3 = TestInput::new(3); - let input4 = TestInput::new(4); - let input5 = TestInput::new(5); - - let plane_id_shader = ( - RendererId("base_params_plane_id".into()), - RendererSpec::Shader(ShaderSpec { - source: include_str!("../../snapshot_tests/shader/layout_planes.wgsl").into(), - }), - ); - - let time_shader = ( - RendererId("base_params_time".into()), - RendererSpec::Shader(ShaderSpec { - source: include_str!("../../snapshot_tests/shader/fade_to_ball.wgsl").into(), - }), - ); - - let texture_count_shader = ( - RendererId("base_params_texture_count".into()), - RendererSpec::Shader(ShaderSpec { - source: include_str!( - "../../snapshot_tests/shader/color_output_with_texture_count.wgsl" - ) - .into(), - }), - ); - - let output_resolution_shader = ( - RendererId("base_params_output_resolution".into()), - RendererSpec::Shader(ShaderSpec { - source: include_str!("../../snapshot_tests/shader/red_border.wgsl").into(), - }), - ); - - Vec::from([ - TestCase { - name: "shader/base_params_plane_id_no_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_plane_id_no_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![plane_id_shader.clone()], - ..Default::default() - }, - TestCase { - name: "shader/base_params_plane_id_5_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_plane_id_5_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![plane_id_shader.clone()], - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - input5.clone(), - ], - ..Default::default() - }, - TestCase { - name: "shader/base_params_time", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/shader/base_params_time.scene.json"), - DEFAULT_RESOLUTION, - ), - renderers: vec![time_shader.clone()], - inputs: vec![input1.clone()], - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(1), - Duration::from_secs(2), - ], - ..Default::default() - }, - TestCase { - name: "shader/base_params_output_resolution", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_output_resolution.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![output_resolution_shader.clone()], - inputs: vec![input1.clone()], - ..Default::default() - }, - TestCase { - name: "shader/base_params_texture_count_no_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_texture_count_no_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![texture_count_shader.clone()], - ..Default::default() - }, - TestCase { - name: "shader/base_params_texture_count_1_input", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_texture_count_1_input.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![texture_count_shader.clone()], - inputs: vec![input1.clone()], - ..Default::default() - }, - TestCase { - name: "shader/base_params_texture_count_2_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/shader/base_params_texture_count_2_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - renderers: vec![texture_count_shader.clone()], - inputs: vec![input1.clone(), input2.clone()], - ..Default::default() - }, - ]) -} - -fn rescaler_snapshot_tests() -> Vec { - let higher_than_default = Resolution { - width: DEFAULT_RESOLUTION.width, - height: DEFAULT_RESOLUTION.height + 100, - }; - let lower_than_default = Resolution { - width: DEFAULT_RESOLUTION.width, - height: DEFAULT_RESOLUTION.height - 100, - }; - let portrait_resolution = Resolution { - width: 360, - height: 640, - }; - Vec::from([ - TestCase { - name: "rescaler/fit_view_with_known_height", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_view_with_known_height.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "rescaler/fit_view_with_known_width", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_view_with_known_width.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "rescaler/fit_view_with_unknown_width_and_height", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_view_with_unknown_width_and_height.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_inverted_aspect_ratio_align_top_left", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream_align_top_left.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_inverted_aspect_ratio_align_bottom_right", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream_align_bottom_right.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_lower_aspect_ratio_align_bottom_right", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream_align_bottom_right.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, lower_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_lower_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, lower_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_higher_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, higher_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_inverted_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fill_input_stream_matching_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fill_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_lower_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, lower_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_higher_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, higher_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_higher_aspect_ratio_small_resolution", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, Resolution { width: higher_than_default.width / 10, height: higher_than_default.height / 10 })], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_inverted_aspect_ratio_align_top_left", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream_align_top_left.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_inverted_aspect_ratio_align_bottom_right", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream_align_bottom_right.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_lower_aspect_ratio_align_bottom_right", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream_align_bottom_right.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, lower_than_default)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_inverted_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, portrait_resolution)], - ..Default::default() - }, - TestCase { - name: "rescaler/fit_input_stream_matching_aspect_ratio", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/rescaler/fit_input_stream.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - ]) -} - -fn tiles_snapshot_tests() -> Vec { - let input1 = TestInput::new(1); - let input2 = TestInput::new(2); - let input3 = TestInput::new(3); - let input4 = TestInput::new(4); - let input5 = TestInput::new(5); - let input6 = TestInput::new(6); - let input7 = TestInput::new(7); - let input8 = TestInput::new(8); - let input9 = TestInput::new(9); - let input10 = TestInput::new(10); - let input11 = TestInput::new(11); - let input12 = TestInput::new(12); - let input13 = TestInput::new(13); - let input14 = TestInput::new(14); - let input15 = TestInput::new(15); - let portrait_resolution = Resolution { - width: 360, - height: 640, - }; - let portrait_input1 = TestInput::new_with_resolution(1, portrait_resolution); - let portrait_input2 = TestInput::new_with_resolution(2, portrait_resolution); - let portrait_input3 = TestInput::new_with_resolution(3, portrait_resolution); - let portrait_input4 = TestInput::new_with_resolution(4, portrait_resolution); - let portrait_input5 = TestInput::new_with_resolution(5, portrait_resolution); - let portrait_input6 = TestInput::new_with_resolution(6, portrait_resolution); - let portrait_input7 = TestInput::new_with_resolution(7, portrait_resolution); - let portrait_input8 = TestInput::new_with_resolution(8, portrait_resolution); - let portrait_input9 = TestInput::new_with_resolution(9, portrait_resolution); - let portrait_input10 = TestInput::new_with_resolution(10, portrait_resolution); - let portrait_input11 = TestInput::new_with_resolution(11, portrait_resolution); - let portrait_input12 = TestInput::new_with_resolution(12, portrait_resolution); - let portrait_input13 = TestInput::new_with_resolution(13, portrait_resolution); - let portrait_input14 = TestInput::new_with_resolution(14, portrait_resolution); - let portrait_input15 = TestInput::new_with_resolution(15, portrait_resolution); - Vec::from([ - TestCase { - name: "tiles_transitions/tile_resize_entire_component_with_parent_transition", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_tile_resize.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_tile_resize_with_view_transition.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - // TODO: This transition does not look great, but it would require automatic - // transitions triggered by a size change (not scene update) - Duration::from_millis(450), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/tile_resize_entire_component_without_parent_transition", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_tile_resize.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_tile_resize.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/change_order_of_3_inputs_with_id", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_all_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_with_3_inputs_3_id_different_order.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/replace_component_by_adding_id", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_with_3_inputs_1_id.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/add_2_inputs_at_the_end_to_3_tiles_scene", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_with_5_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - input5.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/add_input_on_2nd_pos_to_3_tiles_scene", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_with_4_inputs_1_id.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles_transitions/add_input_at_the_end_to_3_tiles_scene", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/end_with_4_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/tiles_transitions/after_end_with_4_inputs_no_id.scene.json"), - DEFAULT_RESOLUTION, - ) - ]), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - ], - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(150), - Duration::from_millis(350), - Duration::from_millis(500), - ], - ..Default::default() - }, - TestCase { - name: "tiles/01_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/01_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/02_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/02_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/03_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/03_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/04_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/04_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/05_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/05_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - input5.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/15_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/15_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - input1.clone(), - input2.clone(), - input3.clone(), - input4.clone(), - input5.clone(), - input6.clone(), - input7.clone(), - input8.clone(), - input9.clone(), - input10.clone(), - input11.clone(), - input12.clone(), - input13.clone(), - input14.clone(), - input15.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/01_portrait_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/01_portrait_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![portrait_input1.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/02_portrait_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/02_portrait_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![portrait_input1.clone(), portrait_input2.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/03_portrait_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/03_portrait_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/05_portrait_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/05_portrait_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - portrait_input4.clone(), - portrait_input5.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/15_portrait_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/15_portrait_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - portrait_input4.clone(), - portrait_input5.clone(), - portrait_input6.clone(), - portrait_input7.clone(), - portrait_input8.clone(), - portrait_input9.clone(), - portrait_input10.clone(), - portrait_input11.clone(), - portrait_input12.clone(), - portrait_input13.clone(), - portrait_input14.clone(), - portrait_input15.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/01_portrait_inputs_on_portrait_output", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/01_portrait_inputs.scene.json"), - portrait_resolution, - ), - inputs: vec![portrait_input1.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/03_portrait_inputs_on_portrait_output", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/03_portrait_inputs.scene.json"), - portrait_resolution, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/03_inputs_on_portrait_output", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/03_inputs.scene.json"), - portrait_resolution, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/05_portrait_inputs_on_portrait_output", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/05_portrait_inputs.scene.json"), - portrait_resolution, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - portrait_input4.clone(), - portrait_input5.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/15_portrait_inputs_on_portrait_output", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/15_portrait_inputs.scene.json"), - portrait_resolution, - ), - inputs: vec![ - portrait_input1.clone(), - portrait_input2.clone(), - portrait_input3.clone(), - portrait_input4.clone(), - portrait_input5.clone(), - portrait_input6.clone(), - portrait_input7.clone(), - portrait_input8.clone(), - portrait_input9.clone(), - portrait_input10.clone(), - portrait_input11.clone(), - portrait_input12.clone(), - portrait_input13.clone(), - portrait_input14.clone(), - portrait_input15.clone(), - ], - ..Default::default() - }, - TestCase { - name: "tiles/align_center_with_03_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/align_center_with_03_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/align_top_left_with_03_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/align_top_left_with_03_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/align_with_margin_and_padding_with_03_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/tiles/align_with_margin_and_padding_with_03_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/margin_with_03_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/margin_with_03_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/margin_and_padding_with_03_inputs", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/tiles/margin_and_padding_with_03_inputs.scene.json" - ), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase { - name: "tiles/padding_with_03_inputs", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/tiles/padding_with_03_inputs.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![input1.clone(), input2.clone(), input3.clone()], - ..Default::default() - }, - TestCase{ - name: "tiles/video_call_with_labels", - scene_updates: Updates::Scene(include_str!("../../snapshot_tests/tiles/video_call_with_labels.scene.json"), DEFAULT_RESOLUTION), - inputs: vec![portrait_input1.clone(), portrait_input2.clone(), portrait_input3.clone()], - ..Default::default() - } - ]) -} - -fn text_snapshot_tests() -> Vec { - Vec::from([ - TestCase { - name: "text/align_center", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/align_center.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/align_right", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/align_right.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/bold_text", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/bold_text.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/dimensions_fitted_column_with_long_text", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/dimensions_fitted_column_with_short_text", - scene_updates: Updates::Scene( - include_str!( - "../../snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/dimensions_fitted", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/dimensions_fitted.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/dimensions_fixed", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/dimensions_fixed.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/dimensions_fixed_with_overflow", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/dimensions_fixed_with_overflow.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/red_text_on_blue_background", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/red_text_on_blue_background.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/wrap_glyph", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/wrap_glyph.scene.json"), - DEFAULT_RESOLUTION, - ), - allowed_error: 325.7, - ..Default::default() - }, - TestCase { - name: "text/wrap_none", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/wrap_none.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - TestCase { - name: "text/wrap_word", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/wrap_word.scene.json"), - DEFAULT_RESOLUTION, - ), - allowed_error: 321.8, - ..Default::default() - }, - TestCase { - // Test if removing text from scene works - name: "text/remove_text_in_view", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/text/align_center.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/view/empty_view.scene.json"), - DEFAULT_RESOLUTION, - ), - ]), - ..Default::default() - }, - TestCase { - // Test if removing text from scene works - name: "text/remove_text_as_root", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/text/root_text.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/view/empty_view.scene.json"), - DEFAULT_RESOLUTION, - ), - ]), - ..Default::default() - }, - TestCase { - name: "text/text_as_root", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/text/root_text.scene.json"), - DEFAULT_RESOLUTION, - ), - ..Default::default() - }, - ]) -} - -fn image_snapshot_tests() -> Vec { - let image_renderer = ( - RendererId("image_jpeg".into()), - RendererSpec::Image(ImageSpec { - src: ImageSource::Url { - url: "https://www.rust-lang.org/static/images/rust-social.jpg".to_string(), - }, - image_type: ImageType::Jpeg, - }), - ); - - Vec::from([ - TestCase { - name: "image/jpeg_as_root", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/image/jpeg_as_root.scene.json"), - DEFAULT_RESOLUTION, - ), - renderers: vec![image_renderer.clone()], - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "image/jpeg_in_view", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/image/jpeg_in_view.scene.json"), - DEFAULT_RESOLUTION, - ), - renderers: vec![image_renderer.clone()], - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "image/jpeg_in_view_overflow_fit", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/image/jpeg_in_view_overflow_fit.scene.json"), - DEFAULT_RESOLUTION, - ), - renderers: vec![image_renderer.clone()], - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - // Test if removing image from scene works - name: "image/remove_jpeg_as_root", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/image/jpeg_as_root.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/view/empty_view.scene.json"), - DEFAULT_RESOLUTION, - ), - ]), - renderers: vec![image_renderer.clone()], - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - // Test if removing image from scene works - name: "image/remove_jpeg_in_view", - scene_updates: Updates::Scenes(vec![ - ( - include_str!("../../snapshot_tests/image/jpeg_in_view.scene.json"), - DEFAULT_RESOLUTION, - ), - ( - include_str!("../../snapshot_tests/view/empty_view.scene.json"), - DEFAULT_RESOLUTION, - ), - ]), - renderers: vec![image_renderer.clone()], - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - ]) -} - -fn transition_snapshot_tests() -> Vec { - Vec::from([ - TestCase { - name: "transition/change_rescaler_absolute_and_send_next_update", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_rescaler_absolute_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_rescaler_absolute_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_rescaler_absolute_after_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(9), - Duration::from_secs(10), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_width_and_send_abort_transition", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_after_end_without_id.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(10), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_width_and_send_next_update", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_after_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(10), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_width", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_width_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(10), - Duration::from_secs(100), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_height", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_height_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_height_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(10), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_absolute", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_secs(0), - Duration::from_secs(5), - Duration::from_secs(9), - Duration::from_secs(10), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_absolute_cubic_bezier", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_cubic_bezier_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_cubic_bezier_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(2500), - Duration::from_secs(5000), - ], - ..Default::default() - }, - TestCase { - name: "transition/change_view_absolute_cubic_bezier_linear_like", - scene_updates: Updates::Scenes(vec![ - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_cubic_bezier_linear_like_start.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ( - include_str!( - "../../snapshot_tests/transition/change_view_absolute_cubic_bezier_linear_like_end.scene.json" - ), - DEFAULT_RESOLUTION, - ), - ]), - timestamps: vec![ - Duration::from_millis(0), - Duration::from_millis(2500), - Duration::from_secs(5000), - ], - ..Default::default() - }, - ]) -} - -fn view_snapshot_tests() -> Vec { - Vec::from([ - TestCase { - name: "view/overflow_hidden_with_input_stream_children", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/overflow_hidden_with_input_stream_children.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new_with_resolution(1, Resolution { width: 180, height: 200 })], - ..Default::default() - }, - TestCase { - name: "view/overflow_hidden_with_view_children", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/overflow_hidden_with_view_children.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![], - ..Default::default() - }, - TestCase { - name: "view/constant_width_views_row", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/constant_width_views_row.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/constant_width_views_row_with_overflow_hidden", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/constant_width_views_row_with_overflow_hidden.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/constant_width_views_row_with_overflow_visible", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/constant_width_views_row_with_overflow_visible.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/constant_width_views_row_with_overflow_fit", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/constant_width_views_row_with_overflow_fit.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/dynamic_width_views_row", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/dynamic_width_views_row.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/dynamic_and_constant_width_views_row", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/dynamic_and_constant_width_views_row.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/dynamic_and_constant_width_views_row_with_overflow", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/dynamic_and_constant_width_views_row_with_overflow.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/constant_width_and_height_views_row", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/constant_width_and_height_views_row.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/view_with_absolute_positioning_partially_covered_by_sibling", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/view_with_absolute_positioning_partially_covered_by_sibling.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/view_with_absolute_positioning_render_over_siblings", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/view_with_absolute_positioning_render_over_siblings.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }, - TestCase { - name: "view/root_view_with_background_color", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/view/root_view_with_background_color.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - } - ]) -} - -fn base_snapshot_tests() -> Vec { - Vec::from([TestCase { - name: "simple_input_pass_through", - scene_updates: Updates::Scene( - include_str!("../../snapshot_tests/simple_input_pass_through.scene.json"), - DEFAULT_RESOLUTION, - ), - inputs: vec![TestInput::new(1)], - ..Default::default() - }]) -} diff --git a/src/snapshot_tests/text_tests.rs b/src/snapshot_tests/text_tests.rs new file mode 100644 index 000000000..da14b75d5 --- /dev/null +++ b/src/snapshot_tests/text_tests.rs @@ -0,0 +1,118 @@ +use super::{scene_from_json, scenes_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn text_tests() { + let mut runner = TestRunner::new(snapshots_path().join("text")); + + runner.add(TestCase { + name: "text/align_center", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/align_center.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/align_right", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/align_right.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/bold_text", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/bold_text.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/dimensions_fitted_column_with_long_text", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/dimensions_fitted_column_with_long_text.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/dimensions_fitted_column_with_short_text", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/dimensions_fitted_column_with_short_text.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/dimensions_fitted", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/dimensions_fitted.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/dimensions_fixed", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/dimensions_fixed.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/dimensions_fixed_with_overflow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/dimensions_fixed_with_overflow.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/red_text_on_blue_background", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/red_text_on_blue_background.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/wrap_glyph", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/wrap_glyph.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/wrap_none", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/wrap_none.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + name: "text/wrap_word", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/wrap_word.scene.json" + )), + ..Default::default() + }); + runner.add(TestCase { + // Test if removing text from scene works + name: "text/remove_text_in_view", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/text/align_center.scene.json"), + include_str!("../../snapshot_tests/view/empty_view.scene.json"), + ]), + ..Default::default() + }); + runner.add(TestCase { + // Test if removing text from scene works + name: "text/remove_text_as_root", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/text/root_text.scene.json"), + include_str!("../../snapshot_tests/view/empty_view.scene.json"), + ]), + ..Default::default() + }); + runner.add(TestCase { + name: "text/text_as_root", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/text/root_text.scene.json" + )), + ..Default::default() + }); + + runner.run() +} diff --git a/src/snapshot_tests/tiles_tests.rs b/src/snapshot_tests/tiles_tests.rs new file mode 100644 index 000000000..2e8f64315 --- /dev/null +++ b/src/snapshot_tests/tiles_tests.rs @@ -0,0 +1,318 @@ +use compositor_render::Resolution; + +use super::{input::TestInput, scene_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn tiles_tests() { + let mut runner = TestRunner::new(snapshots_path().join("tiles")); + + let input1 = TestInput::new(1); + let input2 = TestInput::new(2); + let input3 = TestInput::new(3); + let input4 = TestInput::new(4); + let input5 = TestInput::new(5); + let input6 = TestInput::new(6); + let input7 = TestInput::new(7); + let input8 = TestInput::new(8); + let input9 = TestInput::new(9); + let input10 = TestInput::new(10); + let input11 = TestInput::new(11); + let input12 = TestInput::new(12); + let input13 = TestInput::new(13); + let input14 = TestInput::new(14); + let input15 = TestInput::new(15); + let portrait_resolution = Resolution { + width: 360, + height: 640, + }; + let portrait_input1 = TestInput::new_with_resolution(1, portrait_resolution); + let portrait_input2 = TestInput::new_with_resolution(2, portrait_resolution); + let portrait_input3 = TestInput::new_with_resolution(3, portrait_resolution); + let portrait_input4 = TestInput::new_with_resolution(4, portrait_resolution); + let portrait_input5 = TestInput::new_with_resolution(5, portrait_resolution); + let portrait_input6 = TestInput::new_with_resolution(6, portrait_resolution); + let portrait_input7 = TestInput::new_with_resolution(7, portrait_resolution); + let portrait_input8 = TestInput::new_with_resolution(8, portrait_resolution); + let portrait_input9 = TestInput::new_with_resolution(9, portrait_resolution); + let portrait_input10 = TestInput::new_with_resolution(10, portrait_resolution); + let portrait_input11 = TestInput::new_with_resolution(11, portrait_resolution); + let portrait_input12 = TestInput::new_with_resolution(12, portrait_resolution); + let portrait_input13 = TestInput::new_with_resolution(13, portrait_resolution); + let portrait_input14 = TestInput::new_with_resolution(14, portrait_resolution); + let portrait_input15 = TestInput::new_with_resolution(15, portrait_resolution); + + runner.add(TestCase { + name: "tiles/01_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/01_inputs.scene.json" + )), + inputs: vec![input1.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/02_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/02_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/04_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/04_inputs.scene.json" + )), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/05_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/05_inputs.scene.json" + )), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + input5.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/15_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/15_inputs.scene.json" + )), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + input5.clone(), + input6.clone(), + input7.clone(), + input8.clone(), + input9.clone(), + input10.clone(), + input11.clone(), + input12.clone(), + input13.clone(), + input14.clone(), + input15.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/01_portrait_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/01_portrait_inputs.scene.json" + )), + inputs: vec![portrait_input1.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/02_portrait_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/02_portrait_inputs.scene.json" + )), + inputs: vec![portrait_input1.clone(), portrait_input2.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/03_portrait_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/03_portrait_inputs.scene.json" + )), + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/05_portrait_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/05_portrait_inputs.scene.json" + )), + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + portrait_input4.clone(), + portrait_input5.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/15_portrait_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/15_portrait_inputs.scene.json" + )), + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + portrait_input4.clone(), + portrait_input5.clone(), + portrait_input6.clone(), + portrait_input7.clone(), + portrait_input8.clone(), + portrait_input9.clone(), + portrait_input10.clone(), + portrait_input11.clone(), + portrait_input12.clone(), + portrait_input13.clone(), + portrait_input14.clone(), + portrait_input15.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/01_portrait_inputs_on_portrait_output", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/01_portrait_inputs.scene.json" + )), + resolution: portrait_resolution, + inputs: vec![portrait_input1.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/03_portrait_inputs_on_portrait_output", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/03_portrait_inputs.scene.json" + )), + resolution: portrait_resolution, + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/03_inputs_on_portrait_output", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/03_inputs.scene.json" + )), + resolution: portrait_resolution, + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/05_portrait_inputs_on_portrait_output", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/05_portrait_inputs.scene.json" + )), + resolution: portrait_resolution, + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + portrait_input4.clone(), + portrait_input5.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/15_portrait_inputs_on_portrait_output", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/15_portrait_inputs.scene.json" + )), + resolution: portrait_resolution, + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + portrait_input4.clone(), + portrait_input5.clone(), + portrait_input6.clone(), + portrait_input7.clone(), + portrait_input8.clone(), + portrait_input9.clone(), + portrait_input10.clone(), + portrait_input11.clone(), + portrait_input12.clone(), + portrait_input13.clone(), + portrait_input14.clone(), + portrait_input15.clone(), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/align_center_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/align_center_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/align_top_left_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/align_top_left_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/align_with_margin_and_padding_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/align_with_margin_and_padding_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/margin_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/margin_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/margin_and_padding_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/margin_and_padding_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/padding_with_03_inputs", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/padding_with_03_inputs.scene.json" + )), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles/video_call_with_labels", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/tiles/video_call_with_labels.scene.json" + )), + inputs: vec![ + portrait_input1.clone(), + portrait_input2.clone(), + portrait_input3.clone(), + ], + ..Default::default() + }); + + runner.run() +} diff --git a/src/snapshot_tests/tiles_transitions_tests.rs b/src/snapshot_tests/tiles_transitions_tests.rs new file mode 100644 index 000000000..1b71e75c6 --- /dev/null +++ b/src/snapshot_tests/tiles_transitions_tests.rs @@ -0,0 +1,174 @@ +use std::time::Duration; + +use super::{input::TestInput, scenes_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn tiles_transitions_tests() { + let mut runner = TestRunner::new(snapshots_path().join("tiles_transitions")); + + let input1 = TestInput::new(1); + let input2 = TestInput::new(2); + let input3 = TestInput::new(3); + let input4 = TestInput::new(4); + let input5 = TestInput::new(5); + + runner.add(TestCase { + name: "tiles_transitions/tile_resize_entire_component_with_parent_transition", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/tiles_transitions/start_tile_resize.scene.json"), + include_str!("../../snapshot_tests/tiles_transitions/end_tile_resize_with_view_transition.scene.json"), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + // TODO: This transition does not look great, but it would require automatic + // transitions triggered by a size change (not scene update) + Duration::from_millis(450), + Duration::from_millis(500), + ], + ..Default::default() + }); + + runner.add(TestCase { + name: "tiles_transitions/tile_resize_entire_component_without_parent_transition", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/tiles_transitions/start_tile_resize.scene.json"), + include_str!("../../snapshot_tests/tiles_transitions/end_tile_resize.scene.json"), + ]), + inputs: vec![input1.clone(), input2.clone(), input3.clone()], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles_transitions/change_order_of_3_inputs_with_id", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/tiles_transitions/start_with_3_inputs_all_id.scene.json"), + include_str!("../../snapshot_tests/tiles_transitions/end_with_3_inputs_3_id_different_order.scene.json"), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles_transitions/replace_component_by_adding_id", + scene_updates: scenes_from_json(&[ + include_str!( + "../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json" + ), + include_str!( + "../../snapshot_tests/tiles_transitions/end_with_3_inputs_1_id.scene.json" + ), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles_transitions/add_2_inputs_at_the_end_to_3_tiles_scene", + scene_updates: scenes_from_json(&[ + include_str!( + "../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json" + ), + include_str!( + "../../snapshot_tests/tiles_transitions/end_with_5_inputs_no_id.scene.json" + ), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + input5.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles_transitions/add_input_on_2nd_pos_to_3_tiles_scene", + scene_updates: scenes_from_json(&[ + include_str!( + "../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json" + ), + include_str!( + "../../snapshot_tests/tiles_transitions/end_with_4_inputs_1_id.scene.json" + ), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + runner.add(TestCase { + name: "tiles_transitions/add_input_at_the_end_to_3_tiles_scene", + scene_updates: scenes_from_json(&[ + include_str!( + "../../snapshot_tests/tiles_transitions/start_with_3_inputs_no_id.scene.json" + ), + include_str!( + "../../snapshot_tests/tiles_transitions/end_with_4_inputs_no_id.scene.json" + ), + include_str!( + "../../snapshot_tests/tiles_transitions/after_end_with_4_inputs_no_id.scene.json" + ), + ]), + inputs: vec![ + input1.clone(), + input2.clone(), + input3.clone(), + input4.clone(), + ], + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(150), + Duration::from_millis(350), + Duration::from_millis(500), + ], + ..Default::default() + }); + + runner.run() +} diff --git a/src/snapshot_tests/transition_tests.rs b/src/snapshot_tests/transition_tests.rs new file mode 100644 index 000000000..0a813f698 --- /dev/null +++ b/src/snapshot_tests/transition_tests.rs @@ -0,0 +1,95 @@ +use std::time::Duration; + +use super::{scenes_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn transitions_tests() { + let mut runner = TestRunner::new(snapshots_path().join("transition")); + let default = TestCase { + timestamps: vec![ + Duration::from_millis(0), + Duration::from_millis(2500), + Duration::from_millis(5000), + Duration::from_millis(7500), + Duration::from_millis(9000), + Duration::from_millis(10000), + ], + ..Default::default() + }; + + runner.add(TestCase { + name: "transition/change_rescaler_absolute_and_send_next_update", + scene_updates: scenes_from_json(&[ + include_str!( + "../../snapshot_tests/transition/change_rescaler_absolute_start.scene.json" + ), + include_str!("../../snapshot_tests/transition/change_rescaler_absolute_end.scene.json"), + include_str!( + "../../snapshot_tests/transition/change_rescaler_absolute_after_end.scene.json" + ), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_width_and_send_abort_transition", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_width_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_width_end.scene.json"), + include_str!( + "../../snapshot_tests/transition/change_view_width_after_end_without_id.scene.json" + ), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_width_and_send_next_update", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_width_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_width_end.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_width_after_end.scene.json"), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_width", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_width_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_width_end.scene.json"), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_height", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_height_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_height_end.scene.json"), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_absolute", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_absolute_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_absolute_end.scene.json"), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_absolute_cubic_bezier", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_absolute_cubic_bezier_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_absolute_cubic_bezier_end.scene.json"), + ]), + ..default.clone() + }); + runner.add(TestCase { + name: "transition/change_view_absolute_cubic_bezier_linear_like", + scene_updates: scenes_from_json(&[ + include_str!("../../snapshot_tests/transition/change_view_absolute_cubic_bezier_linear_like_start.scene.json"), + include_str!("../../snapshot_tests/transition/change_view_absolute_cubic_bezier_linear_like_end.scene.json"), + ]), + ..default.clone() + }); + + runner.run() +} diff --git a/src/snapshot_tests/utils.rs b/src/snapshot_tests/utils.rs index d79b8cb67..a9ff71455 100644 --- a/src/snapshot_tests/utils.rs +++ b/src/snapshot_tests/utils.rs @@ -1,40 +1,32 @@ use core::panic; -use std::{ - collections::HashSet, - fs, - path::PathBuf, - sync::{Arc, OnceLock}, - time::Duration, -}; +use std::{io::Write, sync::OnceLock, time::Duration}; +use bytes::BufMut; use compositor_render::{ create_wgpu_ctx, web_renderer, Frame, FrameData, Framerate, Renderer, RendererOptions, - WgpuFeatures, YuvPlanes, + WgpuComponents, WgpuFeatures, YuvPlanes, }; - -use super::test_case::OUTPUT_ID; +use crossbeam_channel::bounded; +use tracing::error; pub const SNAPSHOTS_DIR_NAME: &str = "snapshot_tests/snapshots/render_snapshots"; -fn global_wgpu_ctx( - force_gpu: bool, - features: wgpu::Features, -) -> (Arc, Arc) { - static CTX: OnceLock<(Arc, Arc)> = OnceLock::new(); - - CTX.get_or_init(|| create_wgpu_ctx(force_gpu, features, Default::default()).unwrap()) - .clone() +pub(super) fn frame_to_rgba(frame: &Frame) -> Vec { + match &frame.data { + FrameData::PlanarYuv420(planes) => yuv_frame_to_rgba(frame, planes), + FrameData::PlanarYuvJ420(_) => panic!("unsupported"), + FrameData::InterleavedYuv422(_) => panic!("unsupported"), + FrameData::Rgba8UnormWgpuTexture(texture) => read_rgba_texture(texture).to_vec(), + FrameData::Nv12WgpuTexture(_) => panic!("unsupported"), + } } -pub(super) fn frame_to_rgba(frame: &Frame) -> Vec { - let FrameData::PlanarYuv420(YuvPlanes { +pub(super) fn yuv_frame_to_rgba(frame: &Frame, planes: &YuvPlanes) -> Vec { + let YuvPlanes { y_plane, u_plane, v_plane, - }) = &frame.data - else { - panic!("Wrong pixel format") - }; + } = planes; // Renderer can sometimes produce resolution that is not dividable by 2 let corrected_width = frame.resolution.width - (frame.resolution.width % 2); @@ -61,20 +53,16 @@ pub(super) fn frame_to_rgba(frame: &Frame) -> Vec { rgba_data } -pub(super) fn snapshots_diff(old_snapshot: &[u8], new_snapshot: &[u8]) -> f32 { - if old_snapshot.len() != new_snapshot.len() { - return 10000.0; - } - let square_error: f32 = old_snapshot - .iter() - .zip(new_snapshot) - .map(|(a, b)| (*a as i32 - *b as i32).pow(2) as f32) - .sum(); - - square_error / old_snapshot.len() as f32 +fn get_wgpu_ctx() -> WgpuComponents { + static CTX: OnceLock = OnceLock::new(); + CTX.get_or_init(|| { + create_wgpu_ctx(false, Default::default(), Default::default(), None).unwrap() + }) + .clone() } pub(super) fn create_renderer() -> Renderer { + let wgpu_ctx = get_wgpu_ctx(); let (renderer, _event_loop) = Renderer::new(RendererOptions { web_renderer: web_renderer::WebRendererInitOptions { enable: false, @@ -84,42 +72,98 @@ pub(super) fn create_renderer() -> Renderer { framerate: Framerate { num: 30, den: 1 }, stream_fallback_timeout: Duration::from_secs(3), wgpu_features: WgpuFeatures::default(), - wgpu_ctx: Some(global_wgpu_ctx(false, Default::default())), - load_system_fonts: true, + wgpu_ctx: Some((wgpu_ctx.device.clone(), wgpu_ctx.queue.clone())), + load_system_fonts: false, }) .unwrap(); renderer } -pub fn snapshots_path() -> PathBuf { - PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(SNAPSHOTS_DIR_NAME) +fn read_rgba_texture(texture: &wgpu::Texture) -> bytes::Bytes { + let WgpuComponents { device, queue, .. } = get_wgpu_ctx(); + let buffer = new_download_buffer(&device, texture); + + let mut encoder = device.create_command_encoder(&Default::default()); + copy_to_buffer(&mut encoder, texture, &buffer); + queue.submit(Some(encoder.finish())); + + download_buffer(&device, texture.size(), &buffer) } -pub fn find_unused_snapshots( - produced_snapshots: &HashSet, - snapshots_path: PathBuf, -) -> Vec { - let mut unused_snapshots = Vec::new(); - for entry in fs::read_dir(snapshots_path).unwrap() { - let entry = entry.unwrap(); - if entry.file_type().unwrap().is_dir() { - let mut snapshots = find_unused_snapshots(produced_snapshots, entry.path()); - unused_snapshots.append(&mut snapshots); - continue; - } - if !entry.file_name().to_string_lossy().ends_with(".png") { - continue; - } +fn new_download_buffer(device: &wgpu::Device, texture: &wgpu::Texture) -> wgpu::Buffer { + let size = texture.size(); + let block_size = texture.format().block_copy_size(None).unwrap(); - if !produced_snapshots.contains(&entry.path()) { - unused_snapshots.push(entry.path()) - } - } + device.create_buffer(&wgpu::BufferDescriptor { + label: Some("texture buffer"), + mapped_at_creation: false, + usage: wgpu::BufferUsages::COPY_DST | wgpu::BufferUsages::MAP_READ, + size: (pad_to_256(block_size * size.width) * size.height) as u64, + }) +} - unused_snapshots +fn copy_to_buffer( + encoder: &mut wgpu::CommandEncoder, + texture: &wgpu::Texture, + buffer: &wgpu::Buffer, +) { + let size = texture.size(); + let block_size = texture.format().block_copy_size(None).unwrap(); + encoder.copy_texture_to_buffer( + wgpu::ImageCopyTexture { + aspect: wgpu::TextureAspect::All, + mip_level: 0, + origin: wgpu::Origin3d::ZERO, + texture, + }, + wgpu::ImageCopyBuffer { + buffer, + layout: wgpu::ImageDataLayout { + bytes_per_row: Some(pad_to_256(size.width * block_size)), + rows_per_image: Some(size.height), + offset: 0, + }, + }, + size, + ); } -pub(super) fn snaphot_save_path(test_name: &str, pts: &Duration) -> PathBuf { - let out_file_name = format!("{}_{}_{}.png", test_name, pts.as_millis(), OUTPUT_ID); - snapshots_path().join(out_file_name) +fn download_buffer( + device: &wgpu::Device, + size: wgpu::Extent3d, + source: &wgpu::Buffer, +) -> bytes::Bytes { + let buffer = bytes::BytesMut::with_capacity((size.width * size.height * 4) as usize); + let (s, r) = bounded(1); + source + .slice(..) + .map_async(wgpu::MapMode::Read, move |result| { + if let Err(err) = s.send(result) { + error!("channel send error: {err}") + } + }); + + device.poll(wgpu::MaintainBase::Wait); + + r.recv().unwrap().unwrap(); + let mut buffer = buffer.writer(); + { + let range = source.slice(..).get_mapped_range(); + let chunks = range.chunks(pad_to_256(size.width * 4) as usize); + for chunk in chunks { + buffer + .write_all(&chunk[..(size.width * 4) as usize]) + .unwrap(); + } + }; + source.unmap(); + buffer.into_inner().into() +} + +fn pad_to_256(value: u32) -> u32 { + if value % 256 == 0 { + value + } else { + value + (256 - (value % 256)) + } } diff --git a/src/snapshot_tests/view_tests.rs b/src/snapshot_tests/view_tests.rs new file mode 100644 index 000000000..225983484 --- /dev/null +++ b/src/snapshot_tests/view_tests.rs @@ -0,0 +1,219 @@ +use compositor_render::Resolution; + +use super::{input::TestInput, scene_from_json, snapshots_path, test_case::TestCase, TestRunner}; + +#[test] +fn view_tests() { + let mut runner = TestRunner::new(snapshots_path().join("view")); + let default = TestCase { + inputs: vec![TestInput::new(1)], + ..Default::default() + }; + + runner.add(TestCase { + name: "view/overflow_hidden_with_input_stream_children", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/overflow_hidden_with_input_stream_children.scene.json" + )), + inputs: vec![TestInput::new_with_resolution( + 1, + Resolution { + width: 180, + height: 200, + }, + )], + ..Default::default() + }); + runner.add(TestCase { + name: "view/overflow_hidden_with_view_children", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/overflow_hidden_with_view_children.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/constant_width_views_row", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/constant_width_views_row.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/constant_width_views_row_with_overflow_hidden", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/constant_width_views_row_with_overflow_hidden.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/constant_width_views_row_with_overflow_visible", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/constant_width_views_row_with_overflow_visible.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/constant_width_views_row_with_overflow_fit", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/constant_width_views_row_with_overflow_fit.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/dynamic_width_views_row", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/dynamic_width_views_row.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/dynamic_and_constant_width_views_row", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/dynamic_and_constant_width_views_row.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/dynamic_and_constant_width_views_row_with_overflow", + scene_updates: scene_from_json( + include_str!("../../snapshot_tests/view/dynamic_and_constant_width_views_row_with_overflow.scene.json"), + ), + ..default.clone() + }); + runner.add(TestCase { + name: "view/constant_width_and_height_views_row", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/constant_width_and_height_views_row.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/view_with_absolute_positioning_partially_covered_by_sibling", + scene_updates: scene_from_json( + include_str!("../../snapshot_tests/view/view_with_absolute_positioning_partially_covered_by_sibling.scene.json"), + ), + ..default.clone() + }); + runner.add(TestCase { + name: "view/view_with_absolute_positioning_render_over_siblings", + scene_updates: scene_from_json( + include_str!("../../snapshot_tests/view/view_with_absolute_positioning_render_over_siblings.scene.json"), + ), + ..default.clone() + }); + runner.add(TestCase { + name: "view/root_view_with_background_color", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/root_view_with_background_color.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_width", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_width.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/box_shadow_sibling", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/box_shadow_sibling.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_border_box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_border_box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_box_shadow_overflow_hidden", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_box_shadow_overflow_hidden.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_box_shadow_overflow_fit", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_box_shadow_overflow_fit.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_box_shadow_rescaler_input_stream", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_box_shadow_rescaler_input_stream.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/nested_border_width_radius", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/nested_border_width_radius.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/nested_border_width_radius_aligned", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/nested_border_width_radius_aligned.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/nested_border_width_radius_multi_child", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/nested_border_width_radius_multi_child.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + // it is supposed to be cut off because of the rescaler that wraps it + name: "view/border_radius_border_box_shadow_rescaled", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_border_box_shadow_rescaled.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/root_border_radius_border_box_shadow", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/root_border_radius_border_box_shadow.scene.json" + )), + ..default.clone() + }); + runner.add(TestCase { + name: "view/border_radius_border_box_shadow_rescaled_and_hidden_by_parent", + scene_updates: scene_from_json(include_str!( + "../../snapshot_tests/view/border_radius_border_box_shadow_rescaled_and_hidden_by_parent.scene.json" + )), + ..default.clone() + }); + + runner.run() +} diff --git a/src/snapshot_tests/yuv_tests.rs b/src/snapshot_tests/yuv_tests.rs new file mode 100644 index 000000000..f877f40e0 --- /dev/null +++ b/src/snapshot_tests/yuv_tests.rs @@ -0,0 +1,125 @@ +use core::panic; +use std::{sync::Arc, time::Duration}; + +use compositor_render::{ + scene::{ + BorderRadius, Component, Overflow, Position, RGBAColor, ShaderComponent, Size, + ViewChildrenDirection, ViewComponent, + }, + shader::ShaderSpec, + OutputFrameFormat, RendererId, RendererSpec, Resolution, +}; + +use super::test_case::TestCase; + +fn run_case(test_case: TestCase, expected: &[u8]) { + let mut renderer = test_case.renderer(); + let snapshot = test_case + .snapshot_for_pts(&mut renderer, Duration::ZERO) + .unwrap(); + let failed = snapshot + .data + .iter() + .zip(expected) + .any(|(actual, expected)| u8::abs_diff(*actual, *expected) > 2); + if failed { + panic!("Sample mismatched {:?}", snapshot.data) + } +} + +/// Test how yuv output is generated for smooth color change +#[test] +fn yuv_test_gradient() { + let shader_id = RendererId(Arc::from("example_shader")); + let width = 8; + let height = 2; + + let yuv_case = TestCase { + scene_updates: vec![Component::Shader(ShaderComponent { + id: None, + children: vec![], + shader_id: shader_id.clone(), + shader_param: None, + size: Size { + width: width as f32, + height: height as f32, + }, + })], + renderers: vec![( + shader_id.clone(), + RendererSpec::Shader(ShaderSpec { + source: include_str!("./yuv_tests/gradient.wgsl").into(), + }), + )], + resolution: Resolution { width, height }, + ..Default::default() + }; + let rgb_case = TestCase { + output_format: OutputFrameFormat::RgbaWgpuTexture, + ..yuv_case.clone() + }; + + #[rustfmt::skip] + run_case( + yuv_case, + &[ + 91, 0, 0, 255, 106, 6, 5, 255, 161, 0, 0, 255, 169, 3, 3, 255, 204, 0, 0, 255, 210, 2, 2, 255, 238, 0, 0, 255, 242, 2, 1, 255, + 91, 0, 0, 255, 106, 6, 5, 255, 161, 0, 0, 255, 169, 3, 3, 255, 204, 0, 0, 255, 210, 2, 2, 255, 238, 0, 0, 255, 242, 2, 1, 255, + ], + ); + #[rustfmt::skip] + run_case(rgb_case, + &[ + 71, 0, 0, 255, 120, 0, 0, 255, 152, 0, 0, 255, 177, 0, 0, 255, 198, 0, 0, 255, 216, 0, 0, 255, 233, 0, 0, 255, 248, 0, 0, 255, + 71, 0, 0, 255, 120, 0, 0, 255, 152, 0, 0, 255, 177, 0, 0, 255, 198, 0, 0, 255, 216, 0, 0, 255, 233, 0, 0, 255, 248, 0, 0, 255, + ], + ); +} + +/// Test how yuv output is generated for unified color +#[test] +fn yuv_test_uniform_color() { + let width = 8; + let height = 2; + + let yuv_case = TestCase { + scene_updates: vec![Component::View(ViewComponent { + id: None, + children: vec![], + direction: ViewChildrenDirection::Row, + position: Position::Static { + width: None, + height: None, + }, + transition: None, + overflow: Overflow::Hidden, + background_color: RGBAColor(50, 0, 0, 255), + border_radius: BorderRadius::ZERO, + border_width: 0.0, + border_color: RGBAColor(0, 0, 0, 0), + box_shadow: vec![], + })], + resolution: Resolution { width, height }, + ..Default::default() + }; + let rgb_case = TestCase { + output_format: OutputFrameFormat::RgbaWgpuTexture, + ..yuv_case.clone() + }; + + #[rustfmt::skip] + run_case( + yuv_case, + &[ + 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, + 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255 + ], + ); + #[rustfmt::skip] + run_case(rgb_case, + &[ + 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, + 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255, 50, 0, 0, 255 + ], + ); +} diff --git a/src/snapshot_tests/yuv_tests/gradient.wgsl b/src/snapshot_tests/yuv_tests/gradient.wgsl new file mode 100644 index 000000000..e3fbcdace --- /dev/null +++ b/src/snapshot_tests/yuv_tests/gradient.wgsl @@ -0,0 +1,37 @@ +struct VertexInput { + @location(0) position: vec3, + @location(1) tex_coords: vec2, +} + +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) tex_coords: vec2, +} + +@vertex +fn vs_main(input: VertexInput) -> VertexOutput { + var output: VertexOutput; + + output.position = vec4(input.position, 1.0); + output.tex_coords = input.tex_coords; + + return output; +} + +struct BaseShaderParameters { + plane_id: i32, + time: f32, + output_resolution: vec2, + texture_count: u32, +} + +@group(0) @binding(0) var textures: binding_array, 16>; +@group(2) @binding(0) var sampler_: sampler; + +var base_params: BaseShaderParameters; + +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4 { + return vec4(input.tex_coords.x, 0.0, 0.0, 1.0); +} + diff --git a/ts/.eslintrc.base.json b/ts/.eslintrc.base.json deleted file mode 100644 index 693c84045..000000000 --- a/ts/.eslintrc.base.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "extends": [ - "eslint:recommended", - "plugin:@typescript-eslint/eslint-recommended", - "plugin:@typescript-eslint/recommended", - "plugin:import/recommended", - "plugin:import/typescript", - "prettier" - ], - "plugins": [ - "import", - "prettier" - ], - "parser": "@typescript-eslint/parser", - "parserOptions": { - "project": [ - "tsconfig.json" - ] - }, - "settings": { - "import/parsers": { - "@typescript-eslint/parser": [".ts", ".tsx"] - }, - "import/resolver": { - "typescript": { - "alwaysTryTypes": true, - "project": "**/tsconfig.json" - } - } - }, - "rules": { - "prettier/prettier": ["error"], - "@typescript-eslint/no-explicit-any": [0, {}], - "@typescript-eslint/no-floating-promises": ["error"], - "no-constant-condition": [0], - "@typescript-eslint/no-unused-vars": [ - "error", - { - "args": "all", - "argsIgnorePattern": "^_", - "caughtErrors": "all", - "caughtErrorsIgnorePattern": "^_", - "destructuredArrayIgnorePattern": "^_", - "varsIgnorePattern": "^_", - "ignoreRestSiblings": true - } - ] - } -} diff --git a/ts/.npmrc b/ts/.npmrc new file mode 100644 index 000000000..6143860f5 --- /dev/null +++ b/ts/.npmrc @@ -0,0 +1,2 @@ +hoist-pattern[]=!react +hoist-pattern[]=!react-dom diff --git a/ts/.prettierrc b/ts/.prettierrc deleted file mode 100644 index ca5392be9..000000000 --- a/ts/.prettierrc +++ /dev/null @@ -1,9 +0,0 @@ -{ - "printWidth": 100, - "tabWidth": 2, - "singleQuote": true, - "bracketSameLine": true, - "trailingComma": "es5", - "arrowParens": "avoid", - "endOfLine": "auto" -} diff --git a/ts/.prettierrc.js b/ts/.prettierrc.js new file mode 100644 index 000000000..74da53f68 --- /dev/null +++ b/ts/.prettierrc.js @@ -0,0 +1,9 @@ +export default { + printWidth: 100, + tabWidth: 2, + singleQuote: true, + bracketSameLine: true, + trailingComma: 'es5', + arrowParens: 'avoid', + endOfLine: 'auto', +}; diff --git a/ts/@live-compositor/browser-render/.eslintignore b/ts/@live-compositor/browser-render/.eslintignore deleted file mode 100644 index 4429bff24..000000000 --- a/ts/@live-compositor/browser-render/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -src/generated diff --git a/ts/@live-compositor/browser-render/.eslintrc.json b/ts/@live-compositor/browser-render/.eslintrc.json deleted file mode 100644 index ed5ec9dbf..000000000 --- a/ts/@live-compositor/browser-render/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../../.eslintrc.base.json" - ] -} diff --git a/ts/@live-compositor/browser-render/package.json b/ts/@live-compositor/browser-render/package.json index fd1932dd8..f18e22334 100644 --- a/ts/@live-compositor/browser-render/package.json +++ b/ts/@live-compositor/browser-render/package.json @@ -9,7 +9,7 @@ "build-wasm": "node ./scripts/buildWasm.mjs", "build": "rollup -c", "clean": "rimraf dist", - "prepublishOnly": "npm run clean && npm run build-wasm && npm run build" + "prepublishOnly": "pnpm run clean && pnpm run build-wasm && pnpm run build" }, "author": "", "license": "BUSL-1.1", @@ -22,6 +22,6 @@ "wasm-pack": "^0.13.0" }, "peerDependencies": { - "live-compositor": "^0.1.0" + "live-compositor": "workspace:0.1.0" } } diff --git a/ts/@live-compositor/browser-render/src/api.ts b/ts/@live-compositor/browser-render/src/api.ts index 5072d0c98..fa338d693 100644 --- a/ts/@live-compositor/browser-render/src/api.ts +++ b/ts/@live-compositor/browser-render/src/api.ts @@ -1,4 +1,4 @@ -import { Api } from 'live-compositor'; +import type { Api } from 'live-compositor'; export type Resolution = Api.Resolution; export type ImageSpec = Required>; diff --git a/ts/@live-compositor/browser-render/src/index.ts b/ts/@live-compositor/browser-render/src/index.ts index e6fb704ba..2b260c61c 100644 --- a/ts/@live-compositor/browser-render/src/index.ts +++ b/ts/@live-compositor/browser-render/src/index.ts @@ -1,2 +1,3 @@ export { loadWasmModule } from './wasm'; export * from './renderer'; +export * from './api'; diff --git a/ts/@live-compositor/browser-render/src/renderer.ts b/ts/@live-compositor/browser-render/src/renderer.ts index a621f7b73..50ec76188 100644 --- a/ts/@live-compositor/browser-render/src/renderer.ts +++ b/ts/@live-compositor/browser-render/src/renderer.ts @@ -1,5 +1,5 @@ import { wasm } from './wasm'; -import * as Api from './api'; +import type * as Api from './api'; export type RendererOptions = { /** @@ -8,11 +8,6 @@ export type RendererOptions = { streamFallbackTimeoutMs: number; }; -export type Framerate = { - num: number; - den: number; -}; - export type FrameSet = { ptsMs: number; frames: { [id: string]: Frame }; diff --git a/ts/@live-compositor/browser-render/tsconfig.json b/ts/@live-compositor/browser-render/tsconfig.json index 83ca55649..3a24fb090 100644 --- a/ts/@live-compositor/browser-render/tsconfig.json +++ b/ts/@live-compositor/browser-render/tsconfig.json @@ -1,14 +1,11 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist", "module": "ESNext", "moduleResolution": "bundler", "target": "ESNext", - "noEmit": true, "declaration": false }, - "include": [ - "./src/**/*" - ] + "include": ["./src/**/*"] } diff --git a/ts/@live-compositor/core/.eslintignore b/ts/@live-compositor/core/.eslintignore deleted file mode 100644 index 55294f895..000000000 --- a/ts/@live-compositor/core/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -esm -cjs diff --git a/ts/@live-compositor/core/.eslintrc.json b/ts/@live-compositor/core/.eslintrc.json deleted file mode 100644 index ed5ec9dbf..000000000 --- a/ts/@live-compositor/core/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../../.eslintrc.base.json" - ] -} diff --git a/ts/@live-compositor/core/package.json b/ts/@live-compositor/core/package.json index 498568ecd..a3dffef7f 100644 --- a/ts/@live-compositor/core/package.json +++ b/ts/@live-compositor/core/package.json @@ -12,14 +12,14 @@ "scripts": { "lint": "eslint .", "typecheck": "tsc --noEmit", - "watch": "concurrently \"npm run watch:esm\" \"npm run watch:cjs\"", + "watch": "concurrently \"pnpm run watch:esm\" \"pnpm run watch:cjs\"", "watch:esm": "tsc --watch --preserveWatchOutput", "watch:cjs": "tsc --watch --preserveWatchOutput -p ./tsconfig.cjs.json", - "build": "npm run build:esm && npm run build:cjs", + "build": "pnpm run build:esm && pnpm run build:cjs", "build:esm": "tsc && echo '{\"type\": \"module\"}' > esm/package.json", "build:cjs": "tsc -p ./tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > cjs/package.json", "clean": "rimraf esm cjs", - "prepublishOnly": "npm run clean && npm run build" + "prepublishOnly": "pnpm run clean && pnpm run build" }, "author": "", "license": "MIT", @@ -28,12 +28,14 @@ "/cjs" ], "devDependencies": { + "@types/react": "^18.3.3", "@types/react-reconciler": "0.28.8" }, "dependencies": { "react-reconciler": "0.29.2" }, "peerDependencies": { - "live-compositor": "^0.1.0" + "react": "*", + "live-compositor": "workspace:^0.1.0" } } diff --git a/ts/@live-compositor/core/src/api.ts b/ts/@live-compositor/core/src/api.ts index 8340d8fc6..b2cd348f8 100644 --- a/ts/@live-compositor/core/src/api.ts +++ b/ts/@live-compositor/core/src/api.ts @@ -1,5 +1,7 @@ import { Api } from 'live-compositor'; -import { CompositorManager } from './compositorManager.js'; +import type { CompositorManager } from './compositorManager.js'; +import type { RegisterOutputRequest } from './api/output.js'; +import type { RegisterInputRequest } from './api/input.js'; export { Api }; @@ -24,7 +26,7 @@ export class ApiClient { }); } - public async registerOutput(outptuId: string, request: Api.RegisterOutput): Promise { + public async registerOutput(outptuId: string, request: RegisterOutputRequest): Promise { return this.serverManager.sendRequest({ method: 'POST', route: `/api/output/${encodeURIComponent(outptuId)}/register`, @@ -40,7 +42,7 @@ export class ApiClient { }); } - public async registerInput(inputId: string, request: Api.RegisterInput): Promise { + public async registerInput(inputId: string, request: RegisterInputRequest): Promise { return this.serverManager.sendRequest({ method: 'POST', route: `/api/input/${encodeURIComponent(inputId)}/register`, diff --git a/ts/@live-compositor/core/src/api/input.ts b/ts/@live-compositor/core/src/api/input.ts index 8d74a208f..5c3048d3a 100644 --- a/ts/@live-compositor/core/src/api/input.ts +++ b/ts/@live-compositor/core/src/api/input.ts @@ -1,7 +1,13 @@ -import { Api } from '../api.js'; -import { RegisterInput, Inputs } from 'live-compositor'; +import type { Api } from '../api.js'; +import type { RegisterMp4Input, RegisterRtpInput, Inputs } from 'live-compositor'; -export function intoRegisterInput(input: RegisterInput): Api.RegisterInput { +export type RegisterInputRequest = Api.RegisterInput; + +export type RegisterInput = + | ({ type: 'rtp_stream' } & RegisterRtpInput) + | ({ type: 'mp4' } & RegisterMp4Input); + +export function intoRegisterInput(input: RegisterInput): RegisterInputRequest { if (input.type === 'mp4') { return intoMp4RegisterInput(input); } else if (input.type === 'rtp_stream') { @@ -11,7 +17,7 @@ export function intoRegisterInput(input: RegisterInput): Api.RegisterInput { } } -function intoMp4RegisterInput(input: Inputs.RegisterMp4Input): Api.RegisterInput { +function intoMp4RegisterInput(input: Inputs.RegisterMp4Input): RegisterInputRequest { return { type: 'mp4', url: input.url, @@ -22,7 +28,7 @@ function intoMp4RegisterInput(input: Inputs.RegisterMp4Input): Api.RegisterInput }; } -function intoRtpRegisterInput(input: Inputs.RegisterRtpInput): Api.RegisterInput { +function intoRtpRegisterInput(input: Inputs.RegisterRtpInput): RegisterInputRequest { return { type: 'rtp_stream', port: input.port, diff --git a/ts/@live-compositor/core/src/api/output.ts b/ts/@live-compositor/core/src/api/output.ts index e2a7125f8..8708f0f04 100644 --- a/ts/@live-compositor/core/src/api/output.ts +++ b/ts/@live-compositor/core/src/api/output.ts @@ -1,22 +1,51 @@ -import { RegisterOutput, Api, Outputs } from 'live-compositor'; +import type { + Api, + Outputs, + RegisterRtpOutput, + RegisterMp4Output, + RegisterCanvasOutput, +} from 'live-compositor'; + +export type RegisterOutputRequest = Api.RegisterOutput | RegisterCanvasOutputRequest; + +export type RegisterCanvasOutputRequest = { + type: 'canvas'; + video: OutputCanvasVideoOptions; +}; + +export type OutputCanvasVideoOptions = { + resolution: Api.Resolution; + /** + * HTMLCanvasElement + */ + canvas: any; + initial: Api.Video; +}; + +export type RegisterOutput = + | ({ type: 'rtp_stream' } & RegisterRtpOutput) + | ({ type: 'mp4' } & RegisterMp4Output) + | ({ type: 'canvas' } & RegisterCanvasOutput); export function intoRegisterOutput( output: RegisterOutput, initial: { video?: Api.Video; audio?: Api.Audio } -): Api.RegisterOutput { +): RegisterOutputRequest { if (output.type === 'rtp_stream') { return intoRegisterRtpOutput(output, initial); } else if (output.type === 'mp4') { return intoRegisterMp4Output(output, initial); + } else if (output.type === 'canvas') { + return intoRegisterCanvasOutput(output, initial); } else { - throw new Error(`Unknown input type ${(output as any).type}`); + throw new Error(`Unknown output type ${(output as any).type}`); } } function intoRegisterRtpOutput( output: Outputs.RegisterRtpOutput, initial: { video?: Api.Video; audio?: Api.Audio } -): Api.RegisterOutput { +): RegisterOutputRequest { return { type: 'rtp_stream', port: output.port, @@ -30,7 +59,7 @@ function intoRegisterRtpOutput( function intoRegisterMp4Output( output: Outputs.RegisterMp4Output, initial: { video?: Api.Video; audio?: Api.Audio } -): Api.RegisterOutput { +): RegisterOutputRequest { return { type: 'mp4', path: output.serverPath, @@ -39,6 +68,20 @@ function intoRegisterMp4Output( }; } +function intoRegisterCanvasOutput( + output: Outputs.RegisterCanvasOutput, + initial: { video?: Api.Video; _audio?: Api.Audio } +): RegisterOutputRequest { + return { + type: 'canvas', + video: { + resolution: output.video.resolution, + canvas: output.video.canvas, + initial: initial.video!, + }, + }; +} + function intoOutputVideoOptions( video: Outputs.RtpVideoOptions | Outputs.Mp4VideoOptions, initial: Api.Video diff --git a/ts/@live-compositor/core/src/api/renderer.ts b/ts/@live-compositor/core/src/api/renderer.ts index f75dff1e9..665cee075 100644 --- a/ts/@live-compositor/core/src/api/renderer.ts +++ b/ts/@live-compositor/core/src/api/renderer.ts @@ -1,5 +1,5 @@ -import { Api } from '../api.js'; -import { Renderers } from 'live-compositor'; +import type { Api } from '../api.js'; +import type { Renderers } from 'live-compositor'; export function intoRegisterImage(image: Renderers.RegisterImage): Api.ImageSpec { const source = { diff --git a/ts/@live-compositor/core/src/compositor.ts b/ts/@live-compositor/core/src/compositor.ts index b4f9ee9b4..e06c16f10 100644 --- a/ts/@live-compositor/core/src/compositor.ts +++ b/ts/@live-compositor/core/src/compositor.ts @@ -1,13 +1,11 @@ -import { - _liveCompositorInternals, - RegisterInput, - RegisterOutput, - Renderers, -} from 'live-compositor'; +import type { Renderers } from 'live-compositor'; +import { _liveCompositorInternals } from 'live-compositor'; import { ApiClient } from './api.js'; import Output from './output.js'; -import { CompositorManager } from './compositorManager.js'; +import type { CompositorManager } from './compositorManager.js'; +import type { RegisterOutput } from './api/output.js'; import { intoRegisterOutput } from './api/output.js'; +import type { RegisterInput } from './api/input.js'; import { intoRegisterInput } from './api/input.js'; import { onCompositorEvent } from './event.js'; import { intoRegisterImage, intoRegisterWebRenderer } from './api/renderer.js'; diff --git a/ts/@live-compositor/core/src/compositorManager.ts b/ts/@live-compositor/core/src/compositorManager.ts index 6af287159..ebdcdca73 100644 --- a/ts/@live-compositor/core/src/compositorManager.ts +++ b/ts/@live-compositor/core/src/compositorManager.ts @@ -1,4 +1,4 @@ -import { ApiRequest } from './api.js'; +import type { ApiRequest } from './api.js'; export interface CompositorManager { setupInstance(): Promise; diff --git a/ts/@live-compositor/core/src/event.ts b/ts/@live-compositor/core/src/event.ts index a31145002..f1d6af766 100644 --- a/ts/@live-compositor/core/src/event.ts +++ b/ts/@live-compositor/core/src/event.ts @@ -1,4 +1,5 @@ -import { _liveCompositorInternals, CompositorEvent, CompositorEventType } from 'live-compositor'; +import type { _liveCompositorInternals, CompositorEvent } from 'live-compositor'; +import { CompositorEventType } from 'live-compositor'; type InstanceContextStore = _liveCompositorInternals.InstanceContextStore; diff --git a/ts/@live-compositor/core/src/index.ts b/ts/@live-compositor/core/src/index.ts index 0c2f6703d..fb0b860af 100644 --- a/ts/@live-compositor/core/src/index.ts +++ b/ts/@live-compositor/core/src/index.ts @@ -1,3 +1,5 @@ export { ApiClient, ApiRequest } from './api.js'; export { LiveCompositor } from './compositor.js'; export { CompositorManager } from './compositorManager.js'; +export { RegisterInputRequest, RegisterInput } from './api/input.js'; +export { RegisterOutputRequest, RegisterOutput } from './api/output.js'; diff --git a/ts/@live-compositor/core/src/output.ts b/ts/@live-compositor/core/src/output.ts index bad2aa7b6..ee119ae99 100644 --- a/ts/@live-compositor/core/src/output.ts +++ b/ts/@live-compositor/core/src/output.ts @@ -1,7 +1,10 @@ -import { _liveCompositorInternals, RegisterOutput, View, Outputs } from 'live-compositor'; -import React, { useSyncExternalStore } from 'react'; -import { ApiClient, Api } from './api.js'; +import type { Outputs } from 'live-compositor'; +import { _liveCompositorInternals, View } from 'live-compositor'; +import type React from 'react'; +import { createElement, useSyncExternalStore } from 'react'; +import type { ApiClient, Api } from './api.js'; import Renderer from './renderer.js'; +import type { RegisterOutput } from './api/output.js'; import { intoAudioInputsConfiguration } from './api/output.js'; import { throttle } from './utils.js'; @@ -33,15 +36,16 @@ class Output { this.shouldUpdateWhenReady = true; }; - if (registerRequest.audio) { - this.initialAudioConfig = registerRequest.audio.initial ?? { inputs: [] }; + const hasAudio = 'audio' in registerRequest && !!registerRequest.audio; + if (hasAudio) { + this.initialAudioConfig = registerRequest.audio!.initial ?? { inputs: [] }; } const onUpdate = () => this.throttledUpdate(); - this.outputCtx = new _liveCompositorInternals.OutputContext(onUpdate, !!registerRequest.audio); + this.outputCtx = new _liveCompositorInternals.OutputContext(onUpdate, hasAudio); if (registerRequest.video) { - const rootElement = React.createElement(OutputRootComponent, { + const rootElement = createElement(OutputRootComponent, { instanceStore: store, outputCtx: this.outputCtx, outputRoot: registerRequest.video.root, @@ -124,14 +128,14 @@ function OutputRootComponent({ if (shouldShutdown) { // replace root with view to stop all the dynamic code - return React.createElement(View, {}); + return createElement(View, {}); } const reactCtx = { instanceStore, outputCtx, }; - return React.createElement( + return createElement( _liveCompositorInternals.LiveCompositorContext.Provider, { value: reactCtx }, outputRoot diff --git a/ts/@live-compositor/core/src/renderer.ts b/ts/@live-compositor/core/src/renderer.ts index c4b500e92..acabcb230 100644 --- a/ts/@live-compositor/core/src/renderer.ts +++ b/ts/@live-compositor/core/src/renderer.ts @@ -1,8 +1,9 @@ +// eslint-disable-next-line import/no-named-as-default import Reconciler from 'react-reconciler'; import { DefaultEventPriority, LegacyRoot } from 'react-reconciler/constants.js'; -import { Api } from './api.js'; -import { _liveCompositorInternals } from 'live-compositor'; -import React from 'react'; +import type { Api } from './api.js'; +import type { _liveCompositorInternals } from 'live-compositor'; +import type React from 'react'; type SceneBuilder

= _liveCompositorInternals.SceneBuilder

; type SceneComponent = _liveCompositorInternals.SceneComponent; diff --git a/ts/@live-compositor/core/tsconfig.cjs.json b/ts/@live-compositor/core/tsconfig.cjs.json index 9513b5819..79d0bd8c5 100644 --- a/ts/@live-compositor/core/tsconfig.cjs.json +++ b/ts/@live-compositor/core/tsconfig.cjs.json @@ -1,6 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { + "target": "ES2016", "outDir": "cjs", "module": "commonjs", "moduleResolution": "node", diff --git a/ts/@live-compositor/core/tsconfig.json b/ts/@live-compositor/core/tsconfig.json index 738a96a32..eb9bfd6cf 100644 --- a/ts/@live-compositor/core/tsconfig.json +++ b/ts/@live-compositor/core/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "esm" } diff --git a/ts/@live-compositor/node/.eslintignore b/ts/@live-compositor/node/.eslintignore deleted file mode 100644 index 1521c8b76..000000000 --- a/ts/@live-compositor/node/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/ts/@live-compositor/node/.eslintrc.json b/ts/@live-compositor/node/.eslintrc.json deleted file mode 100644 index ed5ec9dbf..000000000 --- a/ts/@live-compositor/node/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../../.eslintrc.base.json" - ] -} diff --git a/ts/@live-compositor/node/package.json b/ts/@live-compositor/node/package.json index dacd01542..5339dfbb8 100644 --- a/ts/@live-compositor/node/package.json +++ b/ts/@live-compositor/node/package.json @@ -9,7 +9,7 @@ "watch": "tsc --watch --preserveWatchOutput", "build": "tsc", "clean": "rimraf dist", - "prepublishOnly": "npm run clean && npm run build" + "prepublishOnly": "pnpm run clean && pnpm run build" }, "author": "", "license": "MIT", @@ -24,7 +24,7 @@ "@types/ws": "^8.5.12" }, "dependencies": { - "@live-compositor/core": "^0.1.0", + "@live-compositor/core": "workspace:^0.1.0", "fs-extra": "^11.2.0", "node-fetch": "^2.6.7", "tar": "^7.4.3", diff --git a/ts/@live-compositor/node/src/fetch.ts b/ts/@live-compositor/node/src/fetch.ts index 37f009a03..c73c5744a 100644 --- a/ts/@live-compositor/node/src/fetch.ts +++ b/ts/@live-compositor/node/src/fetch.ts @@ -5,7 +5,7 @@ import { Stream } from 'stream'; import { promisify } from 'util'; import fetch from 'node-fetch'; -import { ApiRequest } from '@live-compositor/core'; +import type { ApiRequest } from '@live-compositor/core'; const pipeline = promisify(Stream.pipeline); const httpAgent = new http.Agent({ keepAlive: true }); diff --git a/ts/@live-compositor/node/src/index.ts b/ts/@live-compositor/node/src/index.ts index 716ba8aec..60614db7f 100644 --- a/ts/@live-compositor/node/src/index.ts +++ b/ts/@live-compositor/node/src/index.ts @@ -1,4 +1,5 @@ -import { LiveCompositor as CoreLiveCompositor, CompositorManager } from '@live-compositor/core'; +import type { CompositorManager } from '@live-compositor/core'; +import { LiveCompositor as CoreLiveCompositor } from '@live-compositor/core'; import LocallySpawnedInstance from './manager/locallySpawnedInstance'; import ExistingInstance from './manager/existingInstance'; diff --git a/ts/@live-compositor/node/src/manager/existingInstance.ts b/ts/@live-compositor/node/src/manager/existingInstance.ts index fd7d78ad4..3ea881de4 100644 --- a/ts/@live-compositor/node/src/manager/existingInstance.ts +++ b/ts/@live-compositor/node/src/manager/existingInstance.ts @@ -1,4 +1,4 @@ -import { ApiRequest, CompositorManager } from '@live-compositor/core'; +import type { ApiRequest, CompositorManager } from '@live-compositor/core'; import { sendRequest } from '../fetch'; import { retry, sleep } from '../utils'; diff --git a/ts/@live-compositor/node/src/manager/locallySpawnedInstance.ts b/ts/@live-compositor/node/src/manager/locallySpawnedInstance.ts index 7a7aea9eb..2d97f06e7 100644 --- a/ts/@live-compositor/node/src/manager/locallySpawnedInstance.ts +++ b/ts/@live-compositor/node/src/manager/locallySpawnedInstance.ts @@ -2,9 +2,9 @@ import os from 'os'; import path from 'path'; import { v4 as uuidv4 } from 'uuid'; -import fs from 'fs-extra'; +import * as fs from 'fs-extra'; import * as tar from 'tar'; -import { ApiRequest, CompositorManager } from '@live-compositor/core'; +import type { ApiRequest, CompositorManager } from '@live-compositor/core'; import { download, sendRequest } from '../fetch'; import { retry, sleep } from '../utils'; diff --git a/ts/@live-compositor/node/src/spawn.ts b/ts/@live-compositor/node/src/spawn.ts index ff30811e8..ecc138a2d 100644 --- a/ts/@live-compositor/node/src/spawn.ts +++ b/ts/@live-compositor/node/src/spawn.ts @@ -1,4 +1,5 @@ -import { ChildProcess, SpawnOptions, spawn as nodeSpawn } from 'child_process'; +import type { ChildProcess, SpawnOptions } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; export interface SpawnPromise extends Promise { child: ChildProcess; diff --git a/ts/@live-compositor/node/tsconfig.json b/ts/@live-compositor/node/tsconfig.json index 4e94ea868..b4e69ae1f 100644 --- a/ts/@live-compositor/node/tsconfig.json +++ b/ts/@live-compositor/node/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist" } diff --git a/ts/@live-compositor/web-wasm/package.json b/ts/@live-compositor/web-wasm/package.json new file mode 100644 index 000000000..04b2a5f0c --- /dev/null +++ b/ts/@live-compositor/web-wasm/package.json @@ -0,0 +1,30 @@ +{ + "name": "@live-compositor/web-wasm", + "version": "0.1.0-rc.0", + "description": "", + "main": "dist/index.js", + "scripts": { + "lint": "eslint .", + "typecheck": "tsc --noEmit", + "watch": "tsc --watch --preserveWatchOutput", + "build": "tsc", + "clean": "rimraf dist", + "prepublishOnly": "pnpm run clean && pnpm run build" + }, + "author": "", + "license": "MIT", + "files": [ + "/dist" + ], + "dependencies": { + "@datastructures-js/queue": "^4.2.3", + "@live-compositor/browser-render": "workspace:0.1.0-rc.4", + "@live-compositor/core": "workspace:0.1.0", + "live-compositor": "workspace:^0.1.0", + "mp4box": "^0.5.2", + "path-parser": "^6.1.0" + }, + "devDependencies": { + "@types/react": "^18.3.3" + } +} diff --git a/ts/@live-compositor/web-wasm/src/compositor.ts b/ts/@live-compositor/web-wasm/src/compositor.ts new file mode 100644 index 000000000..18beb9bb8 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/compositor.ts @@ -0,0 +1,88 @@ +import { Renderer } from '@live-compositor/browser-render'; +import { LiveCompositor as CoreLiveCompositor } from '@live-compositor/core'; +import WasmInstance from './manager/wasmInstance'; +import type { RegisterOutput } from './output/registerOutput'; +import { intoRegisterOutput } from './output/registerOutput'; +import type { RegisterInput } from './input/registerInput'; +import { intoRegisterInput } from './input/registerInput'; +import type { RegisterImage } from './renderers'; + +export type LiveCompositorOptions = { + framerate?: Framerate; + streamFallbackTimeoutMs?: number; +}; + +export type Framerate = { + num: number; + den: number; +}; + +export default class LiveCompositor { + private coreCompositor?: CoreLiveCompositor; + private instance?: WasmInstance; + private renderer?: Renderer; + private options: LiveCompositorOptions; + + public constructor(options: LiveCompositorOptions) { + this.options = options; + } + + /* + * Initializes LiveCompositor instance. It needs to be called before any resource is registered. + * Outputs won't produce any results until `start()` is called. + */ + public async init(): Promise { + this.renderer = await Renderer.create({ + streamFallbackTimeoutMs: this.options.streamFallbackTimeoutMs ?? 500, + }); + this.instance = new WasmInstance({ + renderer: this.renderer!, + framerate: this.options.framerate ?? { num: 30, den: 1 }, + }); + this.coreCompositor = new CoreLiveCompositor(this.instance!); + + await this.coreCompositor!.init(); + } + + public async registerOutput(outputId: string, request: RegisterOutput): Promise { + await this.coreCompositor!.registerOutput(outputId, intoRegisterOutput(request)); + } + + public async unregisterOutput(outputId: string): Promise { + await this.coreCompositor!.unregisterOutput(outputId); + } + + public async registerInput(inputId: string, request: RegisterInput): Promise { + await this.coreCompositor!.registerInput(inputId, intoRegisterInput(request)); + } + + public async unregisterInput(inputId: string): Promise { + await this.coreCompositor!.unregisterInput(inputId); + } + + public async registerImage(imageId: string, request: RegisterImage): Promise { + await this.coreCompositor!.registerImage(imageId, request); + } + + public async unregisterImage(imageId: string): Promise { + await this.coreCompositor!.unregisterImage(imageId); + } + + public async registerFont(fontUrl: string): Promise { + await this.renderer!.registerFont(fontUrl); + } + + /** + * Starts processing pipeline. Any previously registered output will start producing video data. + */ + public async start(): Promise { + await this.coreCompositor!.start(); + } + + /** + * Stops processing pipeline. + */ + public stop(): void { + this.instance!.stop(); + } +} diff --git a/ts/@live-compositor/web-wasm/src/eventSender.ts b/ts/@live-compositor/web-wasm/src/eventSender.ts new file mode 100644 index 000000000..5bcd33758 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/eventSender.ts @@ -0,0 +1,63 @@ +import type { CompositorEvent } from 'live-compositor'; +import { CompositorEventType } from 'live-compositor'; + +export class EventSender { + private eventCallback?: (event: object) => void; + + public setEventCallback(eventCallback: (event: object) => void) { + this.eventCallback = eventCallback; + } + + public sendEvent(event: CompositorEvent) { + if (!this.eventCallback) { + console.warn(`Failed to send event: ${event}`); + return; + } + + this.eventCallback!(toWebSocketMessage(event)); + } +} + +function toWebSocketMessage(event: CompositorEvent): WebSocketMessage { + if (event.type == CompositorEventType.OUTPUT_DONE) { + return { + type: event.type, + output_id: event.outputId, + }; + } + + return { + type: event.type, + input_id: event.inputId, + }; +} + +export type WebSocketMessage = + | { + type: CompositorEventType.AUDIO_INPUT_DELIVERED; + input_id: string; + } + | { + type: CompositorEventType.VIDEO_INPUT_DELIVERED; + input_id: string; + } + | { + type: CompositorEventType.AUDIO_INPUT_PLAYING; + input_id: string; + } + | { + type: CompositorEventType.VIDEO_INPUT_PLAYING; + input_id: string; + } + | { + type: CompositorEventType.AUDIO_INPUT_EOS; + input_id: string; + } + | { + type: CompositorEventType.VIDEO_INPUT_EOS; + input_id: string; + } + | { + type: CompositorEventType.OUTPUT_DONE; + output_id: string; + }; diff --git a/ts/@live-compositor/web-wasm/src/index.ts b/ts/@live-compositor/web-wasm/src/index.ts new file mode 100644 index 000000000..4c5a74f2c --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/index.ts @@ -0,0 +1,4 @@ +import WasmInstance from './manager/wasmInstance'; +import LiveCompositor from './compositor'; + +export { WasmInstance, LiveCompositor }; diff --git a/ts/@live-compositor/web-wasm/src/input/decoder/h264Decoder.ts b/ts/@live-compositor/web-wasm/src/input/decoder/h264Decoder.ts new file mode 100644 index 000000000..a7d48f071 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/decoder/h264Decoder.ts @@ -0,0 +1,53 @@ +import { Queue } from '@datastructures-js/queue'; + +const MAX_DECODED_FRAMES = 3; + +export class H264Decoder { + private chunks: Queue; + private frames: Queue; + private decoder: VideoDecoder; + + public constructor() { + this.chunks = new Queue(); + this.frames = new Queue(); + // TODO(noituri): Use web workers + this.decoder = new VideoDecoder({ + output: frame => { + this.frames.push(frame); + }, + error: error => { + console.error(`MP4Decoder error: ${error}`); + }, + }); + } + + public configure(config: VideoDecoderConfig) { + this.decoder.configure(config); + } + + public enqueueChunk(chunk: EncodedVideoChunk) { + this.chunks.push(chunk); + this.decodeChunks(); + } + + /** + * Returns decoded video frames. Frames have to be manually freed from memory + */ + public getFrame(): VideoFrame | undefined { + this.decodeChunks(); + return this.frames.pop(); + } + + private decodeChunks() { + while ( + this.frames.size() < MAX_DECODED_FRAMES && + this.decoder.decodeQueueSize < MAX_DECODED_FRAMES + ) { + const chunk = this.chunks.pop(); + if (!chunk) { + break; + } + this.decoder.decode(chunk); + } + } +} diff --git a/ts/@live-compositor/web-wasm/src/input/input.ts b/ts/@live-compositor/web-wasm/src/input/input.ts new file mode 100644 index 000000000..b8c756a33 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/input.ts @@ -0,0 +1,60 @@ +import type { Frame, InputId } from '@live-compositor/browser-render'; +import { CompositorEventType } from 'live-compositor'; +import type { EventSender } from '../eventSender'; +import type InputSource from './source'; + +/** + * Represents frame produced by decoder. + * `InputFrame` has to be manually freed from the memory by calling `free()` method. Once freed it no longer can be used. + * `Queue` on tick pulls `InputFrame` for each input and once render finishes, manually frees `InputFrame`s. + */ +export type InputFrame = Frame & { + /** + * Frees `InputFrame` from memory. `InputFrame` can not be used after `free()`. + */ + free: () => void; +}; + +export type InputState = 'waiting_for_start' | 'buffering' | 'playing' | 'finished'; + +export class Input { + private id: InputId; + private source: InputSource; + private state: InputState; + private eventSender: EventSender; + + public constructor(id: InputId, source: InputSource, eventSender: EventSender) { + this.id = id; + this.state = 'waiting_for_start'; + this.source = source; + this.eventSender = eventSender; + } + + public start() { + if (this.state !== 'waiting_for_start') { + console.warn(`Tried to start an already started input "${this.id}"`); + return; + } + this.source.start(); + this.state = 'buffering'; + this.eventSender.sendEvent({ + type: CompositorEventType.VIDEO_INPUT_DELIVERED, + inputId: this.id, + }); + } + + public async getFrame(): Promise { + const frame = await this.source.getFrame(); + // TODO(noituri): Handle this better + if (frame && this.state === 'buffering') { + this.state = 'playing'; + this.eventSender.sendEvent({ + type: CompositorEventType.VIDEO_INPUT_PLAYING, + inputId: this.id, + }); + } + // TODO(noituri): Handle EOS + + return frame; + } +} diff --git a/ts/@live-compositor/web-wasm/src/input/mp4/demuxer.ts b/ts/@live-compositor/web-wasm/src/input/mp4/demuxer.ts new file mode 100644 index 000000000..47338d63a --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/mp4/demuxer.ts @@ -0,0 +1,87 @@ +import type { MP4ArrayBuffer, MP4File, MP4Info, Sample } from 'mp4box'; +import MP4Box, { DataStream } from 'mp4box'; + +export type OnConfig = (config: VideoDecoderConfig) => void; + +export type OnChunk = (chunk: EncodedVideoChunk) => void; + +export class MP4Demuxer { + private file: MP4File; + private fileOffset: number; + private onConfig: OnConfig; + private onChunk: OnChunk; + + public constructor(props: { onConfig: OnConfig; onChunk: OnChunk }) { + this.file = MP4Box.createFile(); + this.file.onReady = info => this.onReady(info); + this.file.onSamples = (_id, _user, samples) => this.onSamples(samples); + this.file.onError = (error: string) => { + console.error(`MP4Demuxer error: ${error}`); + }; + this.fileOffset = 0; + + this.onConfig = props.onConfig; + this.onChunk = props.onChunk; + } + + public demux(data: ArrayBuffer) { + const mp4Data = data as MP4ArrayBuffer; + mp4Data.fileStart = this.fileOffset; + this.fileOffset += mp4Data.byteLength; + + this.file.appendBuffer(mp4Data); + } + + public flush() { + this.file.flush(); + } + + private onReady(info: MP4Info) { + if (info.videoTracks.length == 0) { + throw new Error('No video tracks'); + } + + const videoTrack = info.videoTracks[0]; + const codecDescription = this.getCodecDescription(videoTrack.id); + this.onConfig({ + codec: videoTrack.codec, + codedWidth: videoTrack.video.width, + codedHeight: videoTrack.video.height, + description: codecDescription, + }); + + this.file.setExtractionOptions(videoTrack.id); + this.file.start(); + } + + private onSamples(samples: Sample[]) { + for (const sample of samples) { + const chunk = new EncodedVideoChunk({ + type: sample.is_sync ? 'key' : 'delta', + timestamp: (sample.cts * 1_000_000) / sample.timescale, + duration: (sample.duration * 1_000_000) / sample.timescale, + data: sample.data, + }); + + this.onChunk(chunk); + } + } + + private getCodecDescription(trackId: number): Uint8Array { + const track = this.file.getTrackById(trackId); + if (!track) { + throw new Error('Track does not exist'); + } + + for (const entry of track.mdia.minf.stbl.stsd.entries) { + const box = entry.avcC || entry.hvcC || entry.vpcC || entry.av1C; + if (box) { + const stream = new DataStream(undefined, 0, DataStream.BIG_ENDIAN); + box.write(stream); + return new Uint8Array(stream.buffer, 8); + } + } + + throw new Error('Codec description not found'); + } +} diff --git a/ts/examples/vite-browser-render/src/examples/mp4/mp4box.d.ts b/ts/@live-compositor/web-wasm/src/input/mp4/mp4box.d.ts similarity index 97% rename from ts/examples/vite-browser-render/src/examples/mp4/mp4box.d.ts rename to ts/@live-compositor/web-wasm/src/input/mp4/mp4box.d.ts index 4e902b553..5859feb47 100644 --- a/ts/examples/vite-browser-render/src/examples/mp4/mp4box.d.ts +++ b/ts/@live-compositor/web-wasm/src/input/mp4/mp4box.d.ts @@ -14,7 +14,7 @@ declare module 'mp4box' { onError?: (e: string) => void; onSamples?: (id: number, user: object, samples: Sample[]) => void; - getTrackById(id: number): BoxParser.trakBox | undefined; + getTrackById(id: number): TrakBox | undefined; appendBuffer(data: MP4ArrayBuffer): number; start(): void; diff --git a/ts/@live-compositor/web-wasm/src/input/mp4/source.ts b/ts/@live-compositor/web-wasm/src/input/mp4/source.ts new file mode 100644 index 000000000..61a864b28 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/mp4/source.ts @@ -0,0 +1,64 @@ +import { FrameFormat } from '@live-compositor/browser-render'; +import { MP4Demuxer } from './demuxer'; +import { H264Decoder } from '../decoder/h264Decoder'; +import type { InputFrame } from '../input'; +import type InputSource from '../source'; + +export default class MP4Source implements InputSource { + private fileUrl: string; + private fileData?: ArrayBuffer; + private demuxer: MP4Demuxer; + private decoder: H264Decoder; + private frameFormat: VideoPixelFormat; + + public constructor(fileUrl: string) { + this.fileUrl = fileUrl; + this.demuxer = new MP4Demuxer({ + onConfig: config => this.decoder.configure(config), + onChunk: chunk => this.decoder.enqueueChunk(chunk), + }); + this.decoder = new H264Decoder(); + + // Safari does not support conversion to RGBA + // Chrome does not support conversion to YUV + const isSafari = !!(window as any).safari; + this.frameFormat = isSafari ? 'I420' : 'RGBA'; + } + + public async init(): Promise { + const resp = await fetch(this.fileUrl); + this.fileData = await resp.arrayBuffer(); + } + + public start(): void { + if (!this.fileData) { + throw new Error('MP4Source has to be initialized first before processing can be started'); + } + + this.demuxer.demux(this.fileData); + this.demuxer.flush(); + } + + public async getFrame(): Promise { + const frame = this.decoder.getFrame(); + if (!frame) { + return undefined; + } + + const options = { + format: this.frameFormat, + }; + const buffer = new Uint8ClampedArray(frame.allocationSize(options as VideoFrameCopyToOptions)); + await frame.copyTo(buffer, options as VideoFrameCopyToOptions); + + return { + resolution: { + width: frame.displayWidth, + height: frame.displayHeight, + }, + format: this.frameFormat == 'I420' ? FrameFormat.YUV_BYTES : FrameFormat.RGBA_BYTES, + data: buffer, + free: () => frame.close(), + }; + } +} diff --git a/ts/@live-compositor/web-wasm/src/input/registerInput.ts b/ts/@live-compositor/web-wasm/src/input/registerInput.ts new file mode 100644 index 000000000..cae44cd9a --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/registerInput.ts @@ -0,0 +1,15 @@ +import type { RegisterInput as InternalRegisterInput } from '@live-compositor/core'; + +export type RegisterInput = { type: 'mp4' } & RegisterMP4Input; + +export type RegisterMP4Input = { + url: string; +}; + +export function intoRegisterInput(input: RegisterInput): InternalRegisterInput { + if (input.type === 'mp4') { + return { type: 'mp4', url: input.url }; + } else { + throw new Error(`Unknown input type ${(input as any).type}`); + } +} diff --git a/ts/@live-compositor/web-wasm/src/input/source.ts b/ts/@live-compositor/web-wasm/src/input/source.ts new file mode 100644 index 000000000..13269be1f --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/input/source.ts @@ -0,0 +1,20 @@ +import type { RegisterInputRequest } from '@live-compositor/core'; +import type { InputFrame } from './input'; +import MP4Source from './mp4/source'; + +export default interface InputSource { + init(): Promise; + /** + * Starts input processing. `init()` has to be called beforehand. + */ + start(): void; + getFrame(): Promise; +} + +export function sourceFromRequest(request: RegisterInputRequest): InputSource { + if (request.type === 'mp4') { + return new MP4Source(request.url!); + } else { + throw new Error(`Unknown input type ${(request as any).type}`); + } +} diff --git a/ts/@live-compositor/web-wasm/src/manager/wasmInstance.ts b/ts/@live-compositor/web-wasm/src/manager/wasmInstance.ts new file mode 100644 index 000000000..454dc8597 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/manager/wasmInstance.ts @@ -0,0 +1,159 @@ +import type { + ApiRequest, + CompositorManager, + RegisterInputRequest, + RegisterOutputRequest, +} from '@live-compositor/core'; +import type { Renderer, Component, ImageSpec } from '@live-compositor/browser-render'; +import type { Api } from 'live-compositor'; +import { Path } from 'path-parser'; +import type { StopQueueFn } from '../queue'; +import { Queue } from '../queue'; +import { Input } from '../input/input'; +import { EventSender } from '../eventSender'; +import type { Framerate } from '../compositor'; +import { Output } from '../output/output'; +import { sourceFromRequest } from '../input/source'; + +export type OnRegisterCallback = (event: object) => void; + +const apiPath = new Path('/api/:type/:id/:operation'); +const apiStartPath = new Path('/api/start'); + +class WasmInstance implements CompositorManager { + private renderer: Renderer; + private queue: Queue; + private eventSender: EventSender; + private stopQueue?: StopQueueFn; + + public constructor(props: { renderer: Renderer; framerate: Framerate }) { + this.renderer = props.renderer; + this.queue = new Queue(props.framerate, props.renderer); + this.eventSender = new EventSender(); + } + + public async setupInstance(): Promise {} + + public async sendRequest(request: ApiRequest): Promise { + const route = apiPath.test(request.route); + if (!route) { + if (apiStartPath.test(request.route)) { + this.start(); + } + return {}; + } + + if (route.type == 'input') { + await this.handleInputRequest(route.id, route.operation, request.body); + } else if (route.type === 'output') { + this.handleOutputRequest(route.id, route.operation, request.body); + } else if (route.type === 'image') { + await this.handleImageRequest(route.id, route.operation, request.body); + } else if (route.type === 'shader') { + throw new Error('Shaders are not supported'); + } else if (route.type === 'web-renderer') { + throw new Error('Web renderers are not supported'); + } + + return {}; + } + + public registerEventListener(cb: (event: unknown) => void): void { + this.eventSender.setEventCallback(cb); + } + + private start() { + if (this.stopQueue) { + throw new Error('Compositor is already running'); + } + this.stopQueue = this.queue.start(); + } + + public stop() { + // TODO(noituri): Clean all remaining `InputFrame`s + if (this.stopQueue) { + this.stopQueue(); + this.stopQueue = undefined; + } + } + + private async handleInputRequest( + inputId: string, + operation: string, + body?: object + ): Promise { + if (operation === 'register') { + await this.registerInput(inputId, body! as RegisterInputRequest); + } else if (operation === 'unregister') { + this.queue.removeInput(inputId); + this.renderer.unregisterInput(inputId); + } + } + + private handleOutputRequest(outputId: string, operation: string, body?: object) { + if (operation === 'register') { + this.registerOutput(outputId, body! as RegisterOutputRequest); + } else if (operation === 'unregister') { + this.queue.removeOutput(outputId); + this.renderer.unregisterOutput(outputId); + } else if (operation === 'update') { + this.updateScene(outputId, body! as Api.UpdateOutputRequest); + } + } + + private async handleImageRequest( + imageId: string, + operation: string, + body?: object + ): Promise { + if (operation === 'register') { + await this.renderer.registerImage(imageId, body as ImageSpec); + } else if (operation === 'unregister') { + this.renderer.unregisterImage(imageId); + } + } + + private async registerInput(inputId: string, request: RegisterInputRequest): Promise { + const inputSource = sourceFromRequest(request); + await inputSource.init(); + + const input = new Input(inputId, inputSource, this.eventSender); + // `addInput` will throw an exception if input already exists + this.queue.addInput(inputId, input); + this.renderer.registerInput(inputId); + input.start(); + } + + private registerOutput(outputId: string, request: RegisterOutputRequest) { + if (request.video) { + const output = new Output(request); + this.queue.addOutput(outputId, output); + try { + // `updateScene` implicitly registers the output. + // In case of an error, the output has to be manually cleaned up from the renderer. + this.renderer.updateScene( + outputId, + request.video.resolution, + request.video.initial.root as Component + ); + } catch (e) { + this.queue.removeOutput(outputId); + this.renderer.unregisterOutput(outputId); + throw e; + } + } + } + + private updateScene(outputId: string, request: Api.UpdateOutputRequest) { + if (!request.video) { + return; + } + const output = this.queue.getOutput(outputId); + if (!output) { + throw `Unknown output "${outputId}"`; + } + this.renderer.updateScene(outputId, output.resolution, request.video.root as Component); + } +} + +export default WasmInstance; diff --git a/ts/@live-compositor/web-wasm/src/output/canvas.ts b/ts/@live-compositor/web-wasm/src/output/canvas.ts new file mode 100644 index 000000000..5c7c0f7c1 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/output/canvas.ts @@ -0,0 +1,15 @@ +import type { Frame } from '@live-compositor/browser-render'; +import type { OutputSink } from './sink'; + +export default class CanvasSink implements OutputSink { + private ctx: CanvasRenderingContext2D; + + public constructor(canvas: HTMLCanvasElement) { + this.ctx = canvas.getContext('2d')!; + } + + public async send(frame: Frame): Promise { + const resolution = frame.resolution; + this.ctx.putImageData(new ImageData(frame.data, resolution.width, resolution.height), 0, 0); + } +} diff --git a/ts/@live-compositor/web-wasm/src/output/output.ts b/ts/@live-compositor/web-wasm/src/output/output.ts new file mode 100644 index 000000000..236106c75 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/output/output.ts @@ -0,0 +1,22 @@ +import type { Frame, Resolution } from '@live-compositor/browser-render'; +import type { OutputSink } from './sink'; +import CanvasSink from './canvas'; +import type { RegisterOutputRequest } from '@live-compositor/core'; + +export class Output { + private sink: OutputSink; + public readonly resolution: Resolution; + + public constructor(request: RegisterOutputRequest) { + if (request.type === 'canvas') { + this.sink = new CanvasSink(request.video.canvas); + } else { + throw new Error(`Unknown output type ${(request as any).type}`); + } + this.resolution = request.video.resolution; + } + + public async send(frame: Frame): Promise { + await this.sink.send(frame); + } +} diff --git a/ts/@live-compositor/web-wasm/src/output/registerOutput.ts b/ts/@live-compositor/web-wasm/src/output/registerOutput.ts new file mode 100644 index 000000000..c40682280 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/output/registerOutput.ts @@ -0,0 +1,30 @@ +import type { Resolution } from '@live-compositor/browser-render'; +import type { RegisterOutput as InternalRegisterOutput } from '@live-compositor/core'; +import type { ReactElement } from 'react'; + +export type RegisterOutput = { type: 'canvas' } & RegisterCanvasOutput; + +export type RegisterCanvasOutput = { + resolution: Resolution; + canvas: HTMLCanvasElement; + root: ReactElement; +}; + +export function intoRegisterOutput(output: RegisterOutput): InternalRegisterOutput { + if (output.type === 'canvas') { + return fromRegisterCanvasOutput(output); + } else { + throw new Error(`Unknown output type ${(output as any).type}`); + } +} + +function fromRegisterCanvasOutput(output: RegisterCanvasOutput): InternalRegisterOutput { + return { + type: 'canvas', + video: { + resolution: output.resolution, + canvas: output.canvas, + root: output.root, + }, + }; +} diff --git a/ts/@live-compositor/web-wasm/src/output/sink.ts b/ts/@live-compositor/web-wasm/src/output/sink.ts new file mode 100644 index 000000000..7f113a546 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/output/sink.ts @@ -0,0 +1,5 @@ +import type { Frame } from '@live-compositor/browser-render'; + +export interface OutputSink { + send(frame: Frame): Promise; +} diff --git a/ts/@live-compositor/web-wasm/src/queue.ts b/ts/@live-compositor/web-wasm/src/queue.ts new file mode 100644 index 000000000..390026b36 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/queue.ts @@ -0,0 +1,93 @@ +import type { FrameSet, InputId, OutputId, Renderer } from '@live-compositor/browser-render'; +import type { Framerate } from './compositor'; +import type { Input, InputFrame } from './input/input'; +import type { Output } from './output/output'; + +export type StopQueueFn = () => void; + +export class Queue { + private inputs: Record = {}; + private outputs: Record = {}; + private renderer: Renderer; + private framerate: Framerate; + private currentPts: number; + + public constructor(framerate: Framerate, renderer: Renderer) { + this.renderer = renderer; + this.framerate = framerate; + this.currentPts = 0; + } + + public start(): StopQueueFn { + const tickDuration = (1000 * this.framerate.den) / this.framerate.num; + const queueInterval = setInterval(async () => { + await this.onTick(); + this.currentPts += tickDuration; + }, tickDuration); + + return () => clearInterval(queueInterval); + } + + public addInput(inputId: InputId, input: Input) { + if (this.inputs[inputId]) { + throw `Input "${inputId}" already exists`; + } + this.inputs[inputId] = input; + } + + public removeInput(inputId: InputId) { + delete this.inputs[inputId]; + } + + public getInput(inputId: InputId): Input | undefined { + return this.inputs[inputId]; + } + + public addOutput(outputId: OutputId, output: Output) { + if (this.outputs[outputId]) { + throw `Output "${outputId}" already exists`; + } + this.outputs[outputId] = output; + } + + public removeOutput(outputId: OutputId) { + delete this.outputs[outputId]; + } + + public getOutput(outputId: OutputId): Output | undefined { + return this.outputs[outputId]; + } + + private async onTick() { + const inputs = await this.getInputFrames(); + const outputs = this.renderer.render({ + ptsMs: this.currentPts, + frames: inputs, + }); + this.sendOutputs(outputs); + + for (const input of Object.values(inputs)) { + input.free(); + } + } + + private async getInputFrames(): Promise> { + const pendingFrames = Object.entries(this.inputs).map(async ([inputId, input]) => [ + inputId, + await input.getFrame(), + ]); + const frames = await Promise.all(pendingFrames); + return Object.fromEntries(frames.filter(([_inputId, frame]) => !!frame)); + } + + private sendOutputs(outputs: FrameSet) { + for (const [outputId, frame] of Object.entries(outputs.frames)) { + const output = this.outputs[outputId]; + if (!output) { + console.warn(`Output "${outputId}" not found`); + continue; + } + void output.send(frame); + } + } +} diff --git a/ts/@live-compositor/web-wasm/src/renderers.ts b/ts/@live-compositor/web-wasm/src/renderers.ts new file mode 100644 index 000000000..4112db962 --- /dev/null +++ b/ts/@live-compositor/web-wasm/src/renderers.ts @@ -0,0 +1,3 @@ +import type { Renderers } from 'live-compositor'; + +export type RegisterImage = Required>; diff --git a/ts/@live-compositor/web-wasm/tsconfig.json b/ts/@live-compositor/web-wasm/tsconfig.json new file mode 100644 index 000000000..f73765f19 --- /dev/null +++ b/ts/@live-compositor/web-wasm/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "module": "ESNext", + "moduleResolution": "bundler", + "target": "ESNext" + } +} diff --git a/ts/create-live-compositor/.eslintignore b/ts/create-live-compositor/.eslintignore deleted file mode 100644 index 0d842b9e0..000000000 --- a/ts/create-live-compositor/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -dist -templates diff --git a/ts/create-live-compositor/.eslintrc.json b/ts/create-live-compositor/.eslintrc.json deleted file mode 100644 index b80891633..000000000 --- a/ts/create-live-compositor/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../.eslintrc.base.json" - ] -} diff --git a/ts/create-live-compositor/package.json b/ts/create-live-compositor/package.json index 63ed00d4b..53e4ccd5e 100644 --- a/ts/create-live-compositor/package.json +++ b/ts/create-live-compositor/package.json @@ -4,12 +4,12 @@ "description": "", "main": "dist/index.js", "scripts": { - "lint": "eslint .", + "lint": "eslint src", "typecheck": "tsc --noEmit", "watch": "tsc --watch --preserveWatchOutput", "build": "tsc", "clean": "rimraf dist", - "prepublishOnly": "npm run clean && npm run build" + "prepublishOnly": "pnpm run clean && pnpm run build" }, "author": "", "license": "MIT", diff --git a/ts/create-live-compositor/src/createNodeProject.ts b/ts/create-live-compositor/src/createNodeProject.ts index 8295695ae..b028cf35b 100644 --- a/ts/create-live-compositor/src/createNodeProject.ts +++ b/ts/create-live-compositor/src/createNodeProject.ts @@ -1,4 +1,4 @@ -import { ProjectOptions } from './options'; +import type { ProjectOptions } from './options'; import { ensureProjectDir } from './utils/workingdir'; import { runPackageManagerInstall } from './utils/packageManager'; import { applyTemplate } from './template'; diff --git a/ts/create-live-compositor/src/options.ts b/ts/create-live-compositor/src/options.ts index 2eca58f74..21fc8c8b9 100644 --- a/ts/create-live-compositor/src/options.ts +++ b/ts/create-live-compositor/src/options.ts @@ -1,6 +1,7 @@ -import { Choice, confirmPrompt, selectPrompt, textPrompt } from './utils/prompts'; +import type { Choice } from './utils/prompts'; +import { confirmPrompt, selectPrompt, textPrompt } from './utils/prompts'; import path from 'path'; -import { PackageManager } from './utils/packageManager'; +import type { PackageManager } from './utils/packageManager'; import { spawn } from './utils/spawn'; import chalk from 'chalk'; diff --git a/ts/create-live-compositor/src/template.ts b/ts/create-live-compositor/src/template.ts index ef100aa26..3fb22feeb 100644 --- a/ts/create-live-compositor/src/template.ts +++ b/ts/create-live-compositor/src/template.ts @@ -1,4 +1,4 @@ -import fs from 'fs-extra'; +import * as fs from 'fs-extra'; import path from 'path'; const TEMPLATES_ROOT = path.join(__dirname, '../templates'); diff --git a/ts/create-live-compositor/src/utils/prompts.ts b/ts/create-live-compositor/src/utils/prompts.ts index 6a573da67..af05f6757 100644 --- a/ts/create-live-compositor/src/utils/prompts.ts +++ b/ts/create-live-compositor/src/utils/prompts.ts @@ -1,5 +1,6 @@ import { constants } from 'os'; -import prompts, { Answers, Options, Choice as PromptChoice, PromptObject } from 'prompts'; +import type { Answers, Options, Choice as PromptChoice, PromptObject } from 'prompts'; +import { prompt } from 'prompts'; export interface Choice extends PromptChoice { value: T; @@ -9,7 +10,7 @@ async function promptWrapper( questions: PromptObject | Array>, options?: Options ): Promise> { - return await prompts(questions, { + return await prompt(questions, { onCancel() { process.exit(constants.signals.SIGINT + 128); // Exit code 130 used when process is interrupted with ctrl+c. }, diff --git a/ts/create-live-compositor/src/utils/spawn.ts b/ts/create-live-compositor/src/utils/spawn.ts index 8eeb8ea13..baf337700 100644 --- a/ts/create-live-compositor/src/utils/spawn.ts +++ b/ts/create-live-compositor/src/utils/spawn.ts @@ -1,4 +1,5 @@ -import { ChildProcess, SpawnOptions, spawn as nodeSpawn } from 'child_process'; +import type { ChildProcess, SpawnOptions } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; export interface SpawnPromise extends Promise<{ stdout?: string; stderr?: string }> { child: ChildProcess; diff --git a/ts/create-live-compositor/src/utils/workingdir.ts b/ts/create-live-compositor/src/utils/workingdir.ts index f9ad5c186..c9a2ef28c 100644 --- a/ts/create-live-compositor/src/utils/workingdir.ts +++ b/ts/create-live-compositor/src/utils/workingdir.ts @@ -1,4 +1,4 @@ -import fs from 'fs-extra'; +import * as fs from 'fs-extra'; import { confirmPrompt } from './prompts'; export async function ensureProjectDir(directory: string) { diff --git a/ts/create-live-compositor/templates/node-express-zustand/package.json b/ts/create-live-compositor/templates/node-express-zustand/package.json index e528d8d9f..84914d87d 100644 --- a/ts/create-live-compositor/templates/node-express-zustand/package.json +++ b/ts/create-live-compositor/templates/node-express-zustand/package.json @@ -7,19 +7,19 @@ "license": "MIT", "scripts": { "start": "ts-node ./src/index.ts", - "build": "tsc" + "build": "tsc", + "lint": "eslint ." }, "dependencies": { - "@live-compositor/node": "^0.1.0", + "@live-compositor/node": "workspace:^0.1.0", "express": "^4.21.0", - "live-compositor": "^0.1.0", + "live-compositor": "workspace:^0.1.0", "react": "^18.3.1", "zustand": "4.5.5" }, "devDependencies": { "@types/express": "^4.17.21", "@types/node": "^20.14.10", - "@types/react": "^18.3.3", - "typescript": "^5.5.3" + "@types/react": "^18.3.3" } } diff --git a/ts/create-live-compositor/templates/node-express-zustand/src/App.tsx b/ts/create-live-compositor/templates/node-express-zustand/src/App.tsx index 18e87dcde..49fb7befb 100644 --- a/ts/create-live-compositor/templates/node-express-zustand/src/App.tsx +++ b/ts/create-live-compositor/templates/node-express-zustand/src/App.tsx @@ -25,28 +25,28 @@ function OutputScene() { function Instructions() { return ( - + - Open index.ts and get started. - - + Open index.ts and get started. + + This example renders static text and sends the output stream via RTP to local port 8001. Generated code includes helpers in liveCompositorFfplayHelper.ts that display the output stream using ffplay, make sure to remove them for any real production use. - - Where to go next? - + + Where to go next? + - ./src/App.tsx defines content of the streams. - + - ./src/routes.ts controls HTTP API that can be used to interact with this example. - + - ./compositor.tsx exposes LiveCompositor instance that can be used to add/remove new streams/images/shader. - + - ./store.ts implements global store using Zustand, enabling express API and React to share common settings. diff --git a/ts/create-live-compositor/templates/node-express-zustand/src/liveCompositorFfplayHelper.ts b/ts/create-live-compositor/templates/node-express-zustand/src/liveCompositorFfplayHelper.ts index 990951311..4eb1241c0 100644 --- a/ts/create-live-compositor/templates/node-express-zustand/src/liveCompositorFfplayHelper.ts +++ b/ts/create-live-compositor/templates/node-express-zustand/src/liveCompositorFfplayHelper.ts @@ -1,7 +1,8 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; -import { ChildProcess, spawn as nodeSpawn, SpawnOptions } from 'child_process'; +import type { ChildProcess, SpawnOptions } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; const TMP_SDP_DIR = path.join(os.tmpdir(), 'live-composiotor-sdp'); diff --git a/ts/create-live-compositor/templates/node-express-zustand/src/routes.ts b/ts/create-live-compositor/templates/node-express-zustand/src/routes.ts index 9be6f98cc..2d60cae90 100644 --- a/ts/create-live-compositor/templates/node-express-zustand/src/routes.ts +++ b/ts/create-live-compositor/templates/node-express-zustand/src/routes.ts @@ -1,8 +1,9 @@ +import type { Express } from 'express'; import express, { json } from 'express'; import { Compositor } from './compositor'; import { store } from './store'; -export const app = express(); +export const app: Express = express(); app.use(json()); diff --git a/ts/create-live-compositor/templates/node-minimal/package.json b/ts/create-live-compositor/templates/node-minimal/package.json index 140b6e47f..de646f9f7 100644 --- a/ts/create-live-compositor/templates/node-minimal/package.json +++ b/ts/create-live-compositor/templates/node-minimal/package.json @@ -7,11 +7,12 @@ "license": "MIT", "scripts": { "start": "ts-node ./src/App.tsx", - "build": "tsc" + "build": "tsc", + "lint": "eslint ." }, "dependencies": { - "@live-compositor/node": "^0.1.0", - "live-compositor": "^0.1.0", + "@live-compositor/node": "workspace:^0.1.0", + "live-compositor": "workspace:^0.1.0", "react": "^18.3.1" }, "devDependencies": { diff --git a/ts/create-live-compositor/templates/node-minimal/src/index.tsx b/ts/create-live-compositor/templates/node-minimal/src/index.tsx index 3fb0890f3..61562af6d 100644 --- a/ts/create-live-compositor/templates/node-minimal/src/index.tsx +++ b/ts/create-live-compositor/templates/node-minimal/src/index.tsx @@ -4,13 +4,13 @@ import { ffplayStartPlayerAsync } from './liveCompositorFfplayHelper'; function App() { return ( - + - Open index.ts and get started - - - This example renders static text and sends the output stream via RTP to local port - 8001. Generated code includes helpers in liveCompositorFfplayHelper.ts that display the output + Open index.ts and get started + + + This example renders static text and sends the output stream via RTP to local port 8001. + Generated code includes helpers in liveCompositorFfplayHelper.ts that display the output stream using ffplay, make sure to remove them for any real production use. diff --git a/ts/create-live-compositor/templates/node-minimal/src/liveCompositorFfplayHelper.ts b/ts/create-live-compositor/templates/node-minimal/src/liveCompositorFfplayHelper.ts index d6229fe54..f7a70823c 100644 --- a/ts/create-live-compositor/templates/node-minimal/src/liveCompositorFfplayHelper.ts +++ b/ts/create-live-compositor/templates/node-minimal/src/liveCompositorFfplayHelper.ts @@ -1,7 +1,8 @@ import os from 'os'; import path from 'path'; import fs from 'fs'; -import { ChildProcess, spawn as nodeSpawn, SpawnOptions } from 'child_process'; +import type { ChildProcess, SpawnOptions } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; const TMP_SDP_DIR = path.join(os.tmpdir(), 'live-composiotor-sdp'); diff --git a/ts/create-live-compositor/tsconfig.json b/ts/create-live-compositor/tsconfig.json index e95d8d0fd..a6da6b6cd 100644 --- a/ts/create-live-compositor/tsconfig.json +++ b/ts/create-live-compositor/tsconfig.json @@ -1,9 +1,7 @@ { - "extends": "../tsconfig.base.json", + "extends": "../tsconfig.json", "compilerOptions": { "outDir": "dist" }, - "include": [ - "./src/**/*" - ] + "include": ["src"] } diff --git a/ts/eslint.config.js b/ts/eslint.config.js new file mode 100644 index 000000000..95422988a --- /dev/null +++ b/ts/eslint.config.js @@ -0,0 +1,101 @@ +import globals from 'globals'; + +import eslintRecommended from '@eslint/js'; +import eslintConfigPrettier from 'eslint-config-prettier'; + +import pluginImport from 'eslint-plugin-import'; +import pluginPrettierRecommended from 'eslint-plugin-prettier/recommended'; +import { plugin as tsEslintPlugin } from 'typescript-eslint'; +import reactHooks from 'eslint-plugin-react-hooks'; +import reactRefresh from 'eslint-plugin-react-refresh'; + +import tsParser from '@typescript-eslint/parser'; + +export default [ + eslintRecommended.configs.recommended, + pluginImport.flatConfigs.recommended, + pluginPrettierRecommended, + eslintConfigPrettier, + { + files: ['**/*.{js,jsx,ts,tsx}'], + ignores: ['.prettierrc.js'], + plugins: { + '@typescript-eslint': tsEslintPlugin, + }, + languageOptions: { + parser: tsParser, + parserOptions: { + project: [ + 'tsconfig.json', + '**/examples/vite-browser-render/tsconfig.node.json', + '**/examples/vite-browser-render/tsconfig.app.json', + ], + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + globals: { + ...globals.browser, + ...globals.node, + }, + }, + settings: { + 'import/parsers': { + '@typescript-eslint/parser': ['.ts', '.tsx'], + }, + 'import/resolver': { + typescript: { + alwaysTryTypes: true, + project: '**/tsconfig.json', + }, + }, + }, + rules: { + 'prettier/prettier': ['error'], + 'import/no-unresolved': 'error', + '@typescript-eslint/no-explicit-any': [0, {}], + '@typescript-eslint/no-floating-promises': ['error'], + 'no-constant-condition': [0], + 'no-unused-vars': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + args: 'all', + argsIgnorePattern: '^_', + caughtErrors: 'all', + caughtErrorsIgnorePattern: '^_', + destructuredArrayIgnorePattern: '^_', + varsIgnorePattern: '^_', + ignoreRestSiblings: true, + vars: 'local', + }, + ], + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + }, + ], + }, + }, + { + files: ['examples/vite-browser-render/**/*.{ts,tsx}'], + plugins: { + 'react-hooks': reactHooks, + 'react-refresh': reactRefresh, + }, + rules: { + ...reactHooks.configs.recommended.rules, + 'react-refresh/only-export-components': ['error', { allowConstantExport: true }], + }, + }, + { + ignores: [ + '**/dist/**/*', + '**/cjs/**/*', + '**/esm/**/*', + '**/generated/**/*', + '**/*.d.ts', + '**/*.mjs', + ], + }, +]; diff --git a/ts/examples/README.md b/ts/examples/README.md index 521486ce7..90cd682b9 100644 --- a/ts/examples/README.md +++ b/ts/examples/README.md @@ -12,11 +12,11 @@ To launch any of the above examples go to `node-examples` directory and run: ```bash -npm run ts-node +pnpm run ts-node ``` e.g. ```bash -npm run ts-node ./src/simple.tsx +pnpm run ts-node ./src/simple.tsx ``` diff --git a/ts/examples/node-examples/.eslintignore b/ts/examples/node-examples/.eslintignore deleted file mode 100644 index 1521c8b76..000000000 --- a/ts/examples/node-examples/.eslintignore +++ /dev/null @@ -1 +0,0 @@ -dist diff --git a/ts/examples/node-examples/.eslintrc.json b/ts/examples/node-examples/.eslintrc.json deleted file mode 100644 index ed5ec9dbf..000000000 --- a/ts/examples/node-examples/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../../.eslintrc.base.json" - ] -} diff --git a/ts/examples/node-examples/package.json b/ts/examples/node-examples/package.json index d67373b74..487e9953d 100644 --- a/ts/examples/node-examples/package.json +++ b/ts/examples/node-examples/package.json @@ -15,12 +15,17 @@ "author": "", "license": "MIT", "dependencies": { - "@live-compositor/node": "^0.1.0", - "@types/fs-extra": "^11.0.4", - "@types/node": "^20.14.10", + "@live-compositor/node": "workspace:^0.1.0", "fs-extra": "^11.2.0", - "live-compositor": "^0.1.0", + "live-compositor": "workspace:^0.1.0", "node-fetch": "^2.6.7", + "react": "^18.3.1", "ts-node": "^10.9.2" + }, + "devDependencies": { + "@types/fs-extra": "^11.0.4", + "@types/node": "^20.14.10", + "@types/node-fetch": "^2.6.11", + "@types/react": "^18.3.3" } } diff --git a/ts/examples/node-examples/src/audio.tsx b/ts/examples/node-examples/src/audio.tsx index 1516b5b55..8234739aa 100644 --- a/ts/examples/node-examples/src/audio.tsx +++ b/ts/examples/node-examples/src/audio.tsx @@ -15,13 +15,13 @@ function ExampleApp() { return ( - - + + ); } -function InputTile({ inputId, mute }: { inputId: string; mute: boolean }) { +function InputTile({ inputId, muted }: { inputId: string; muted: boolean }) { const [volume, setVolume] = useState(1.0); useEffect(() => { @@ -38,11 +38,11 @@ function InputTile({ inputId, mute }: { inputId: string; mute: boolean }) { return ( - + - - - Input ID: {inputId}, volume: {volume.toFixed(2)} {mute ? 'muted' : 'live'} + + + Input ID: {inputId}, volume: {volume.toFixed(2)} {muted ? 'muted' : 'live'} diff --git a/ts/examples/node-examples/src/dynamic-inputs.tsx b/ts/examples/node-examples/src/dynamic-inputs.tsx index 241bd6f7f..11fbf818c 100644 --- a/ts/examples/node-examples/src/dynamic-inputs.tsx +++ b/ts/examples/node-examples/src/dynamic-inputs.tsx @@ -9,13 +9,13 @@ function ExampleApp() { {Object.values(inputs).map(input => !input.videoState ? ( - + Waiting for stream {input.inputId} to connect ) : input.videoState === 'playing' ? ( ) : input.videoState === 'finished' ? ( - + Stream {input.inputId} finished ) : ( @@ -32,8 +32,9 @@ function InputTile({ inputId }: { inputId: string }) { - - + + Input ID: {inputId} diff --git a/ts/examples/node-examples/src/dynamic-outputs.tsx b/ts/examples/node-examples/src/dynamic-outputs.tsx index 9f4718498..0cb4c34a5 100644 --- a/ts/examples/node-examples/src/dynamic-outputs.tsx +++ b/ts/examples/node-examples/src/dynamic-outputs.tsx @@ -2,7 +2,7 @@ import LiveCompositor from '@live-compositor/node'; import { Text, InputStream, Tiles, Rescaler, View, useInputStreams } from 'live-compositor'; import { downloadAllAssets, gstReceiveTcpStream, sleep } from './utils'; import path from 'path'; -import fs from 'fs-extra'; +import { mkdirp } from 'fs-extra'; function ExampleApp() { const inputs = useInputStreams(); @@ -21,8 +21,9 @@ function InputTile({ inputId }: { inputId: string }) { - - + + Input ID: {inputId} @@ -31,7 +32,7 @@ function InputTile({ inputId }: { inputId: string }) { } async function run() { - await fs.mkdirp(path.join(__dirname, '../.workingdir')); + await mkdirp(path.join(__dirname, '../.workingdir')); await downloadAllAssets(); const compositor = new LiveCompositor(); await compositor.init(); diff --git a/ts/examples/node-examples/src/dynamic-text.tsx b/ts/examples/node-examples/src/dynamic-text.tsx index 1d93ae4d0..17dc13d9b 100644 --- a/ts/examples/node-examples/src/dynamic-text.tsx +++ b/ts/examples/node-examples/src/dynamic-text.tsx @@ -36,14 +36,14 @@ function PartialText(props: PartialTextProps) { return ( - {props.text.substring(0, textPart.characters)} + {props.text.substring(0, textPart.characters)} ); } function ExampleApp() { return ( - + diff --git a/ts/examples/node-examples/src/simple.tsx b/ts/examples/node-examples/src/simple.tsx index c2811c84d..d65eca2ac 100644 --- a/ts/examples/node-examples/src/simple.tsx +++ b/ts/examples/node-examples/src/simple.tsx @@ -8,7 +8,7 @@ type PartialTextProps = { }; function SimpleComponent(props: PartialTextProps) { - return {props.text}; + return {props.text}; } function ExampleApp() { @@ -27,12 +27,12 @@ function ExampleApp() { }); return ( - + {[...Array(count)].map((_value, index) => ( ))} - Text component example (fontSize={30}) + Text component example (fontSize={30}) Raw text example (default fontSize={50}) Counter: {count} diff --git a/ts/examples/node-examples/src/utils.ts b/ts/examples/node-examples/src/utils.ts index d0d97683b..bb35367b9 100644 --- a/ts/examples/node-examples/src/utils.ts +++ b/ts/examples/node-examples/src/utils.ts @@ -1,6 +1,7 @@ import path from 'path'; -import fs from 'fs-extra'; -import { ChildProcess, spawn as nodeSpawn } from 'child_process'; +import fs, { mkdirp, pathExists, writeFile } from 'fs-extra'; +import type { ChildProcess } from 'child_process'; +import { spawn as nodeSpawn } from 'child_process'; import { promisify } from 'util'; import { Stream } from 'stream'; import fetch from 'node-fetch'; @@ -14,7 +15,7 @@ export async function ffplayStartPlayerAsync( video_port: number, audio_port: number | undefined = undefined ): Promise<{ spawn_promise: SpawnPromise }> { - await fs.mkdirp(TMP_SDP_DIR); + await mkdirp(TMP_SDP_DIR); let sdpFilePath; if (audio_port === undefined) { sdpFilePath = path.join(TMP_SDP_DIR, `video_input_${video_port}.sdp`); @@ -89,7 +90,7 @@ async function writeVideoAudioSdpFile( audio_port: number, destination: string ): Promise { - await fs.writeFile( + await writeFile( destination, ` v=0 @@ -108,7 +109,7 @@ a=rtcp-mux } async function writeVideoSdpFile(ip: string, port: number, destination: string): Promise { - await fs.writeFile( + await writeFile( destination, ` v=0 @@ -144,10 +145,10 @@ const exampleAssets = [ export async function downloadAllAssets(): Promise { const downloadDir = path.join(__dirname, '../.assets'); - await fs.mkdirp(downloadDir); + await mkdirp(downloadDir); for (const asset of exampleAssets) { - if (!(await fs.pathExists(path.join(downloadDir, asset.path)))) { + if (!(await pathExists(path.join(downloadDir, asset.path)))) { await download(asset.url, path.join(downloadDir, asset.path)); } } diff --git a/ts/examples/node-examples/tsconfig.json b/ts/examples/node-examples/tsconfig.json index f3274a1fb..7382eee8a 100644 --- a/ts/examples/node-examples/tsconfig.json +++ b/ts/examples/node-examples/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../tsconfig.base.json", + "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "dist", "jsx": "react-jsx" diff --git a/ts/examples/vite-browser-render/.gitignore b/ts/examples/vite-browser-render/.gitignore index 1f05e5163..c0468f536 100644 --- a/ts/examples/vite-browser-render/.gitignore +++ b/ts/examples/vite-browser-render/.gitignore @@ -11,6 +11,7 @@ node_modules dist dist-ssr *.local +*.tsbuildinfo # Editor directories and files .vscode/* diff --git a/ts/examples/vite-browser-render/eslint.config.js b/ts/examples/vite-browser-render/eslint.config.js deleted file mode 100644 index c973d7f03..000000000 --- a/ts/examples/vite-browser-render/eslint.config.js +++ /dev/null @@ -1,25 +0,0 @@ -import js from '@eslint/js'; -import globals from 'globals'; -import reactHooks from 'eslint-plugin-react-hooks'; -import reactRefresh from 'eslint-plugin-react-refresh'; -import tseslint from 'typescript-eslint'; - -export default tseslint.config( - { ignores: ['dist'] }, - { - extends: [js.configs.recommended, ...tseslint.configs.recommended], - files: ['**/*.{ts,tsx}'], - languageOptions: { - ecmaVersion: 2020, - globals: globals.browser, - }, - plugins: { - 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, - }, - rules: { - ...reactHooks.configs.recommended.rules, - 'react-refresh/only-export-components': ['warn', { allowConstantExport: true }], - }, - } -); diff --git a/ts/examples/vite-browser-render/package.json b/ts/examples/vite-browser-render/package.json index f558dbad2..546f90406 100644 --- a/ts/examples/vite-browser-render/package.json +++ b/ts/examples/vite-browser-render/package.json @@ -11,23 +11,22 @@ "preview": "vite preview" }, "dependencies": { - "@live-compositor/browser-render": "^0.1.0-rc.4", + "@live-compositor/browser-render": "workspace:0.1.0-rc.4", + "@live-compositor/web-wasm": "workspace:0.1.0-rc.0", "mp4box": "^0.5.2", "react": "^18.3.1", "react-dom": "^18.3.1" }, "devDependencies": { - "@eslint/js": "^9.9.0", "@types/react": "^18.3.3", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.9", - "globals": "^15.9.0", "typescript": "^5.5.3", "typescript-eslint": "^8.0.1", "vite": "^5.4.1", "vite-plugin-static-copy": "^1.0.6" + }, + "peerDependencies": { + "live-compositor": "workspace:^0.1.0" } } diff --git a/ts/examples/vite-browser-render/src/App.css b/ts/examples/vite-browser-render/src/App.css index 11c2ca5f6..4beee6d83 100644 --- a/ts/examples/vite-browser-render/src/App.css +++ b/ts/examples/vite-browser-render/src/App.css @@ -6,6 +6,8 @@ } .card { + display: flex; + flex-direction: column; padding: 2em; } @@ -17,3 +19,4 @@ .examples-tabs button { margin: 5px; } + diff --git a/ts/examples/vite-browser-render/src/App.tsx b/ts/examples/vite-browser-render/src/App.tsx index 139510364..9259b9bc6 100644 --- a/ts/examples/vite-browser-render/src/App.tsx +++ b/ts/examples/vite-browser-render/src/App.tsx @@ -4,8 +4,8 @@ import Counter from './examples/Counter'; import MP4Player from './examples/MP4Player'; const EXAMPLES = { - 'counter': , - 'mp4': + counter: , + mp4: , }; function App() { @@ -18,12 +18,9 @@ function App() { -
- {EXAMPLES[currentExample]} -
+
{EXAMPLES[currentExample]}
); } - export default App; diff --git a/ts/examples/vite-browser-render/src/examples/Counter.tsx b/ts/examples/vite-browser-render/src/examples/Counter.tsx index 49647411a..7b5042c17 100644 --- a/ts/examples/vite-browser-render/src/examples/Counter.tsx +++ b/ts/examples/vite-browser-render/src/examples/Counter.tsx @@ -1,12 +1,10 @@ - import { useEffect, useRef, useState } from 'react'; -import { useRenderer } from './utils'; +import { loadWasmModule, Renderer } from '@live-compositor/browser-render'; function Counter() { const canvasRef = useRef(null); const [count, setCount] = useState(0); const renderer = useRenderer(); - useEffect(() => { if (renderer == null) { return; @@ -14,7 +12,7 @@ function Counter() { renderer.updateScene( 'output', - { width: 256, height: 256 }, + { width: 300, height: 300 }, { type: 'view', children: [ @@ -70,4 +68,30 @@ function Counter() { ); } +function useRenderer(): Renderer | null { + const [renderer, setRenderer] = useState(null); + useEffect(() => { + const setupRenderer = async () => { + await loadWasmModule('./assets/live-compositor.wasm'); + const renderer = await Renderer.create({ + streamFallbackTimeoutMs: 500, + }); + + await renderer.registerImage('img', { + asset_type: 'gif', + url: 'https://media.tenor.com/eFPFHSN4rJ8AAAAM/example.gif', + }); + await renderer.registerFont( + 'https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6Vc.ttf' + ); + + setRenderer(renderer); + }; + + setupRenderer().catch(err => console.error(err)); + }, []); + + return renderer; +} + export default Counter; diff --git a/ts/examples/vite-browser-render/src/examples/MP4Player.tsx b/ts/examples/vite-browser-render/src/examples/MP4Player.tsx index 7e17ab609..39cddd8d9 100644 --- a/ts/examples/vite-browser-render/src/examples/MP4Player.tsx +++ b/ts/examples/vite-browser-render/src/examples/MP4Player.tsx @@ -1,139 +1,21 @@ -import { MP4ArrayBuffer } from 'mp4box'; -import { MP4Decoder } from './mp4/decoder'; -import { FrameFormat, FrameSet } from '@live-compositor/browser-render'; -import { useEffect, useRef } from 'react'; -import { useRenderer } from './utils'; +import { useCallback, useEffect, useState } from 'react'; +import { LiveCompositor } from '@live-compositor/web-wasm'; +import { InputStream, Text, useInputStreams, View } from 'live-compositor'; -const BUNNY_URL = 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'; +const BUNNY_URL = + 'https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'; function MP4Player() { - const canvasRef = useRef(null); - const renderer = useRenderer(); + const [compositor, canvasRef] = useCompositor(); useEffect(() => { - if (renderer == null) { + if (compositor == null) { return; } - renderer.registerInput('bunny_video'); - renderer.updateScene( - 'output', - { - width: 1280, - height: 720, - }, - { - type: 'view', - background_color_rgba: '#000000FF', - children: [ - { - type: 'view', - top: 300, - left: 500, - children: [ - { - type: 'text', - font_size: 30, - font_family: 'Noto Sans', - text: 'Loading MP4 file', - align: 'right', - }, - ], - }, - ], - } - ); - - const decoder = new MP4Decoder(); - fetch(BUNNY_URL) - .then(resp => resp.arrayBuffer()) - .then(videoData => { - renderer.updateScene( - 'output', - { - width: 1280, - height: 720, - }, - { - type: 'view', - width: 1280, - height: 720, - background_color_rgba: '#000000FF', - children: [ - { - type: 'input_stream', - input_id: 'bunny_video', - }, - { - type: 'view', - width: 230, - height: 40, - background_color_rgba: '#000000FF', - bottom: 20, - left: 500, - children: [ - { - type: 'text', - font_size: 30, - font_family: 'Noto Sans', - text: 'Playing MP4 file', - align: 'center', - }, - ], - }, - ], - } - ); - - decoder.decode(videoData as MP4ArrayBuffer); - }); - - const canvas = canvasRef!.current!; - const ctx = canvas.getContext('2d'); - - let pts = 0; - const renderInterval = setInterval(async () => { - const inputs: FrameSet = { - ptsMs: pts, - frames: {}, - }; - - const frame = decoder.nextFrame(); - if (frame) { - const frameOptions = { - format: 'RGBA', - }; - const buffer = new Uint8ClampedArray( - frame.allocationSize(frameOptions as VideoFrameCopyToOptions) - ); - await frame.copyTo(buffer, frameOptions as VideoFrameCopyToOptions); - - inputs.frames['bunny_video'] = { - resolution: { - width: frame.displayWidth, - height: frame.displayHeight, - }, - format: FrameFormat.RGBA_BYTES, - data: buffer, - }; - } - - const outputs = renderer.render(inputs); - const output = outputs.frames['output']; - ctx!.putImageData( - new ImageData(output.data, output.resolution.width, output.resolution.height), - 0, - 0 - ); - - if (frame) { - frame.close(); - } - pts += 30; - }, 30); - - return () => clearInterval(renderInterval); - }, [renderer]) + void compositor.start(); + return () => compositor.stop(); + }, [compositor]); return ( <> @@ -144,4 +26,69 @@ function MP4Player() { ); } +function Scene() { + const inputs = useInputStreams(); + const inputState = inputs['bunny_video']?.videoState; + + if (inputState !== 'playing') { + return ( + + + Loading MP4 file + + + ); + } + + return ( + + + + Playing MP4 file + + + ); +} + +function useCompositor(): [LiveCompositor | undefined, (canvas: HTMLCanvasElement) => void] { + const [compositor, setCompositor] = useState(undefined); + const canvasRef = useCallback(async (canvas: HTMLCanvasElement) => { + if (!canvas) { + return; + } + + const setupCompositor = async () => { + const compositor = new LiveCompositor({ + framerate: { + num: 30, + den: 1, + }, + streamFallbackTimeoutMs: 500, + }); + + await compositor.init(); + + setCompositor(compositor); + + await compositor.registerFont( + 'https://fonts.gstatic.com/s/notosans/v36/o-0mIpQlx3QUlC5A4PNB6Ryti20_6n1iPHjcz6L1SoM-jCpoiyD9A-9a6Vc.ttf' + ); + void compositor.registerInput('bunny_video', { type: 'mp4', url: BUNNY_URL }); + await compositor.registerOutput('output', { + type: 'canvas', + canvas: canvas, + resolution: { + width: 1280, + height: 720, + }, + root: , + }); + }; + + await setupCompositor(); + }, []); + + return [compositor, canvasRef]; +} + export default MP4Player; diff --git a/ts/examples/vite-browser-render/src/examples/mp4/decoder.ts b/ts/examples/vite-browser-render/src/examples/mp4/decoder.ts index a63fe2973..c7d50f78d 100644 --- a/ts/examples/vite-browser-render/src/examples/mp4/decoder.ts +++ b/ts/examples/vite-browser-render/src/examples/mp4/decoder.ts @@ -1,4 +1,5 @@ -import MP4Box, { DataStream, MP4ArrayBuffer, MP4File, MP4Info, Sample, TrakBox } from "mp4box"; +import type { MP4ArrayBuffer, MP4File, MP4Info, Sample, TrakBox } from 'mp4box'; +import MP4Box, { DataStream } from 'mp4box'; const MAX_FRAMEBUFFER_SIZE = 3; @@ -39,7 +40,10 @@ export class MP4Decoder { } private enqueueNextChunks() { - while (this.decoder.decodeQueueSize < MAX_FRAMEBUFFER_SIZE && this.frames.length < MAX_FRAMEBUFFER_SIZE) { + while ( + this.decoder.decodeQueueSize < MAX_FRAMEBUFFER_SIZE && + this.frames.length < MAX_FRAMEBUFFER_SIZE + ) { const chunk = this.chunks.shift(); if (!chunk) { return null; @@ -54,6 +58,7 @@ export class MP4Decoder { console.log(`Using codec: ${videoTrack.codec}`); const trak = this.file.getTrackById(videoTrack.id); + if (!trak) return; const description = getCodecDescription(trak); if (!description) { console.error('Codec description not found'); diff --git a/ts/examples/vite-browser-render/src/examples/utils.ts b/ts/examples/vite-browser-render/src/examples/utils.ts index 8a8dd02ff..94121ae2d 100644 --- a/ts/examples/vite-browser-render/src/examples/utils.ts +++ b/ts/examples/vite-browser-render/src/examples/utils.ts @@ -1,5 +1,5 @@ -import { loadWasmModule, Renderer } from "@live-compositor/browser-render"; -import { useEffect, useState } from "react"; +import { loadWasmModule, Renderer } from '@live-compositor/browser-render'; +import { useEffect, useState } from 'react'; export function useRenderer(): Renderer | null { const [renderer, setRenderer] = useState(null); diff --git a/ts/examples/vite-browser-render/ts-declarations/mp4box.d.ts b/ts/examples/vite-browser-render/ts-declarations/mp4box.d.ts new file mode 100644 index 000000000..5859feb47 --- /dev/null +++ b/ts/examples/vite-browser-render/ts-declarations/mp4box.d.ts @@ -0,0 +1,112 @@ +declare module 'mp4box' { + export class DataStream { + constructor(buffer?: ArrayBuffer, byteOffset?: number, endianness?: boolean); + + get buffer(): ArrayBuffer; + set buffer(v: ArrayBuffer); + + static LITTLE_ENDIAN: boolean; + static BIG_ENDIAN: boolean; + } + + export interface MP4File { + onReady?: (info: MP4Info) => void; + onError?: (e: string) => void; + onSamples?: (id: number, user: object, samples: Sample[]) => void; + + getTrackById(id: number): TrakBox | undefined; + + appendBuffer(data: MP4ArrayBuffer): number; + start(): void; + stop(): void; + flush(): void; + + setExtractionOptions(id: number, user?: object, options?: ExtractionOptions): void; + } + + export interface MP4MediaTrack { + id: number; + movie_duration: number; + track_width: number; + track_height: number; + timescale: number; + duration: number; + bitrate: number; + codec: string; + } + + export interface MP4VideoTrack extends MP4MediaTrack { + video: { + width: number; + height: number; + }; + } + + export interface MP4AudioTrack extends MP4MediaTrack { + audio: { + sample_size: number; + sample_rate: number; + channel_count: number; + }; + } + + export type MP4Track = MP4VideoTrack | MP4AudioTrack; + + export interface MP4Info { + duration: number; + timescale: number; + tracks: MP4Track[]; + audioTracks: MP4AudioTrack[]; + videoTracks: MP4VideoTrack[]; + } + + export interface Sample { + timescale: number; + data: ArrayBuffer; + size: number; + duration: number; + cts: number; + dts: number; + is_sync: boolean; + depends: number; + } + + export interface ExtractionOptions { + nbSamples: number; + } + + export type MP4ArrayBuffer = ArrayBuffer & { fileStart: number }; + + export class Box { + write(stream: DataStream): void; + } + + export class TrakBox extends Box { + mdia: MdiaBox; + } + + export class MdiaBox extends Box { + minf: MinfBox; + } + + export class MinfBox extends Box { + stbl: StblBox; + } + + export class StblBox extends Box { + stsd: StsdBox; + } + + export class StsdBox extends Box { + entries: Description[]; + } + + export interface Description { + avcC?: Box; + hvcC?: Box; + vpcC?: Box; + av1C?: Box; + } + + export function createFile(): MP4File; +} diff --git a/ts/examples/vite-browser-render/tsconfig.app.json b/ts/examples/vite-browser-render/tsconfig.app.json index f0a235055..27b709d0a 100644 --- a/ts/examples/vite-browser-render/tsconfig.app.json +++ b/ts/examples/vite-browser-render/tsconfig.app.json @@ -20,5 +20,5 @@ "noUnusedParameters": true, "noFallthroughCasesInSwitch": true }, - "include": ["src"] + "include": ["src", "ts-declarations"] } diff --git a/ts/examples/vite-browser-render/vite.config.ts b/ts/examples/vite-browser-render/vite.config.ts index b0bea3b86..46676fe10 100644 --- a/ts/examples/vite-browser-render/vite.config.ts +++ b/ts/examples/vite-browser-render/vite.config.ts @@ -13,7 +13,10 @@ export default defineConfig({ viteStaticCopy({ targets: [ { - src: path.join(path.dirname(require.resolve('@live-compositor/browser-render')), 'live-compositor.wasm'), + src: path.join( + path.dirname(require.resolve('@live-compositor/browser-render')), + 'live-compositor.wasm' + ), dest: 'assets', }, ], diff --git a/ts/live-compositor/.eslintignore b/ts/live-compositor/.eslintignore deleted file mode 100644 index 55294f895..000000000 --- a/ts/live-compositor/.eslintignore +++ /dev/null @@ -1,2 +0,0 @@ -esm -cjs diff --git a/ts/live-compositor/.eslintrc.json b/ts/live-compositor/.eslintrc.json deleted file mode 100644 index b80891633..000000000 --- a/ts/live-compositor/.eslintrc.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "../.eslintrc.base.json" - ] -} diff --git a/ts/live-compositor/README.md b/ts/live-compositor/README.md index 0e5622986..237dc9cf9 100644 --- a/ts/live-compositor/README.md +++ b/ts/live-compositor/README.md @@ -19,8 +19,8 @@ import { View, Text, InputStream, Rescaler } from 'live-compositor'; function ExampleApp() { return ( - - + + Example label diff --git a/ts/live-compositor/package.json b/ts/live-compositor/package.json index cd1ae012d..bb6515f2e 100644 --- a/ts/live-compositor/package.json +++ b/ts/live-compositor/package.json @@ -12,14 +12,14 @@ "scripts": { "lint": "eslint .", "typecheck": "tsc --noEmit", - "watch": "concurrently \"npm run watch:esm\" \"npm run watch:cjs\"", + "watch": "concurrently \"pnpm run watch:esm\" \"pnpm run watch:cjs\"", "watch:esm": "tsc --watch --preserveWatchOutput", "watch:cjs": "tsc --watch --preserveWatchOutput -p ./tsconfig.cjs.json", - "build": "npm run build:esm && npm run build:cjs", + "build": "pnpm run build:esm && pnpm run build:cjs", "build:esm": "tsc && echo '{\"type\": \"module\"}' > esm/package.json", "build:cjs": "tsc -p ./tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > cjs/package.json", "clean": "rimraf esm cjs", - "prepublishOnly": "npm run clean && npm run build" + "prepublishOnly": "pnpm run clean && pnpm run build" }, "author": "", "license": "MIT", diff --git a/ts/live-compositor/src/component.ts b/ts/live-compositor/src/component.ts index abd075010..ef2b79038 100644 --- a/ts/live-compositor/src/component.ts +++ b/ts/live-compositor/src/component.ts @@ -1,5 +1,8 @@ -import React, { useId } from 'react'; -import * as Api from './api.js'; +import type React from 'react'; +import { createElement, useId } from 'react'; +import type * as Api from './api.js'; + +export const DEFAULT_FONT_SIZE = 50; type ComponentProps

= { children?: React.ReactNode; id?: Api.ComponentId } & P; @@ -13,7 +16,7 @@ export function createCompositorComponent

( const { children, ...otherProps } = props; const autoId = useId(); - return React.createElement( + return createElement( 'compositor', { sceneBuilder, @@ -29,7 +32,7 @@ export function sceneComponentIntoApi(component: SceneComponent): Api.Component return { type: 'text', text: component, - font_size: 50, + font_size: DEFAULT_FONT_SIZE, }; } return component; diff --git a/ts/live-compositor/src/components/Image.ts b/ts/live-compositor/src/components/Image.ts index 4d8fa7483..445dde715 100644 --- a/ts/live-compositor/src/components/Image.ts +++ b/ts/live-compositor/src/components/Image.ts @@ -1,5 +1,6 @@ -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent } from '../component.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent } from '../component.js'; +import type { Api } from '../index.js'; export type ImageProps = { children?: undefined; diff --git a/ts/live-compositor/src/components/InputStream.ts b/ts/live-compositor/src/components/InputStream.ts index 27ef54016..833b6c0ef 100644 --- a/ts/live-compositor/src/components/InputStream.ts +++ b/ts/live-compositor/src/components/InputStream.ts @@ -1,6 +1,7 @@ import { createElement } from 'react'; -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent } from '../component.js'; +import type * as Api from '../api.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent } from '../component.js'; import { useAudioInput } from '../hooks.js'; export type InputStreamProps = { @@ -21,18 +22,18 @@ export type InputStreamProps = { /** * Mute audio. */ - mute?: boolean; + muted?: boolean; }; -type AudioPropNames = 'mute' | 'volume' | 'disableAudioControl'; +type AudioPropNames = 'muted' | 'volume' | 'disableAudioControl'; const InnerInputStream = createCompositorComponent>(sceneBuilder); function InputStream(props: InputStreamProps) { - const { mute, volume, ...otherProps } = props; + const { muted, volume, ...otherProps } = props; useAudioInput(props.inputId, { - volume: mute ? 0 : (volume ?? 1), + volume: muted ? 0 : (volume ?? 1), }); return createElement(InnerInputStream, otherProps); } diff --git a/ts/live-compositor/src/components/Rescaler.ts b/ts/live-compositor/src/components/Rescaler.ts index a1080ed47..d749d15a9 100644 --- a/ts/live-compositor/src/components/Rescaler.ts +++ b/ts/live-compositor/src/components/Rescaler.ts @@ -1,19 +1,15 @@ -import React from 'react'; -import * as Api from '../api.js'; -import { intoApiTransition, Transition } from './common.js'; -import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component.js'; +import type React from 'react'; +import type * as Api from '../api.js'; +import type { Transition } from './common.js'; +import { intoApiTransition } from './common.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, sceneComponentIntoApi } from '../component.js'; -export type RescalerProps = { - children: React.ReactElement | string | number; - - /** - * Id of a component. - */ - id?: Api.ComponentId; +export type RescalerStyle = { /** * (**default=`"fit"`**) Resize mode: */ - mode?: Api.RescaleMode; + resizeMode?: Api.RescaleMode; /** * (**default=`"center"`**) Horizontal alignment. */ @@ -66,6 +62,19 @@ export type RescalerProps = { * absolutely positioned, instead of being laid out by its parent. */ rotation?: number; +}; + +export type RescalerProps = { + children: React.ReactElement | string | number; + + /** + * Id of a component. + */ + id?: Api.ComponentId; + /** + * Rescaler styling properties + */ + style?: RescalerStyle; /** * Defines how this component will behave during a scene update. This will only have an * effect if the previous scene already contained a `Rescaler` component with the same id. @@ -75,25 +84,29 @@ export type RescalerProps = { const Rescaler = createCompositorComponent(sceneBuilder); -function sceneBuilder(props: RescalerProps, children: SceneComponent[]): Api.Component { +function sceneBuilder( + { id, style, transition }: RescalerProps, + children: SceneComponent[] +): Api.Component { if (children?.length !== 1) { throw new Error('Exactly one child is required for Rescaler component'); } + return { type: 'rescaler', - id: props.id, + id: id, child: sceneComponentIntoApi(children[0]), - mode: props.mode, - horizontal_align: props.horizontalAlign, - vertical_align: props.verticalAlign, - width: props.width, - height: props.height, - top: props.top, - bottom: props.bottom, - left: props.left, - right: props.right, - rotation: props.rotation, - transition: props.transition && intoApiTransition(props.transition), + mode: style?.resizeMode, + horizontal_align: style?.horizontalAlign, + vertical_align: style?.verticalAlign, + width: style?.width, + height: style?.height, + top: style?.top, + bottom: style?.bottom, + left: style?.left, + right: style?.right, + rotation: style?.rotation, + transition: transition && intoApiTransition(transition), }; } diff --git a/ts/live-compositor/src/components/Shader.ts b/ts/live-compositor/src/components/Shader.ts index 73809d5db..c429f804d 100644 --- a/ts/live-compositor/src/components/Shader.ts +++ b/ts/live-compositor/src/components/Shader.ts @@ -1,5 +1,6 @@ -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component.js'; +import type * as Api from '../api.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, sceneComponentIntoApi } from '../component.js'; export type ShaderProps = { /** diff --git a/ts/live-compositor/src/components/Text.ts b/ts/live-compositor/src/components/Text.ts index a5d5b9959..eb51e9223 100644 --- a/ts/live-compositor/src/components/Text.ts +++ b/ts/live-compositor/src/components/Text.ts @@ -1,14 +1,9 @@ -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent } from '../component.js'; +import type * as Api from '../api.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, DEFAULT_FONT_SIZE } from '../component.js'; import { intoApiRgbaColor } from './common.js'; -export type TextProps = { - children?: (string | number)[] | string | number; - - /** - * Id of a component. - */ - id?: Api.ComponentId; +export type TextStyle = { /** * Width of a texture that text will be rendered on. If not provided, the resulting texture * will be sized based on the defined text but limited to `max_width` value. @@ -54,7 +49,7 @@ export type TextProps = { /** * (**default=`"normal"`**) Font style. The selected font needs to support the specified style. */ - style?: Api.TextStyle; + fontStyle?: Api.TextStyle; /** * (**default=`"left"`**) Text align. */ @@ -66,29 +61,45 @@ export type TextProps = { /** * (**default=`"normal"`**) Font weight. The selected font needs to support the specified weight. */ - weight?: Api.TextWeight; + fontWeight?: Api.TextWeight; +}; + +export type TextProps = { + children?: (string | number)[] | string | number; + + /** + * Id of a component. + */ + id?: Api.ComponentId; + + /** + * Text styling properties + */ + style?: TextStyle; }; const Text = createCompositorComponent(sceneBuilder); function sceneBuilder(props: TextProps, children: SceneComponent[]): Api.Component { + const { id, style } = props; + return { type: 'text', - id: props.id, + id: id, text: children.map(child => (typeof child === 'string' ? child : String(child))).join(''), - width: props.width, - height: props.height, - max_width: props.maxWidth, - max_height: props.maxHeight, - font_size: props.fontSize, - line_height: props.lineHeight, - color_rgba: props.color && intoApiRgbaColor(props.color), - background_color_rgba: props.backgroundColor && intoApiRgbaColor(props.backgroundColor), - font_family: props.fontFamily, - style: props.style, - align: props.align, - wrap: props.wrap, - weight: props.weight, + width: style?.width, + height: style?.height, + max_width: style?.maxWidth, + max_height: style?.maxHeight, + font_size: style?.fontSize ?? DEFAULT_FONT_SIZE, + line_height: style?.lineHeight, + color_rgba: style?.color && intoApiRgbaColor(style?.color), + background_color_rgba: style?.backgroundColor && intoApiRgbaColor(style?.backgroundColor), + font_family: style?.fontFamily, + style: style?.fontStyle, + align: style?.align, + wrap: style?.wrap, + weight: style?.fontWeight, }; } diff --git a/ts/live-compositor/src/components/Tiles.ts b/ts/live-compositor/src/components/Tiles.ts index b900f95ca..de098c4ea 100644 --- a/ts/live-compositor/src/components/Tiles.ts +++ b/ts/live-compositor/src/components/Tiles.ts @@ -1,12 +1,10 @@ -import * as Api from '../api.js'; -import { intoApiRgbaColor, intoApiTransition, Transition } from './common.js'; -import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component.js'; +import type * as Api from '../api.js'; +import type { Transition } from './common.js'; +import { intoApiRgbaColor, intoApiTransition } from './common.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, sceneComponentIntoApi } from '../component.js'; -export type TilesProps = { - /** - * Id of a component. - */ - id?: Api.ComponentId; +export type TilesStyle = { /** * Width of a component in pixels. Exact behavior might be different based on the parent * component: @@ -47,6 +45,17 @@ export type TilesProps = { * (**default=`"center"`**) Vertical alignment of tiles. */ verticalAlign?: Api.VerticalAlign; +}; + +export type TilesProps = { + /** + * Id of a component. + */ + id?: Api.ComponentId; + /** + * Tiles styling properties + */ + style?: TilesStyle; /** * Defines how this component will behave during a scene update. This will only have an * effect if the previous scene already contained a `Tiles` component with the same id. @@ -56,20 +65,23 @@ export type TilesProps = { const Tiles = createCompositorComponent(sceneBuilder); -function sceneBuilder(props: TilesProps, children: SceneComponent[]): Api.Component { +function sceneBuilder( + { id, style, transition }: TilesProps, + children: SceneComponent[] +): Api.Component { return { type: 'tiles', - id: props.id, + id: id, children: children.map(sceneComponentIntoApi), - width: props.width, - height: props.height, - background_color_rgba: props.backgroundColor && intoApiRgbaColor(props.backgroundColor), - tile_aspect_ratio: props.tileAspectRatio, - margin: props.margin, - padding: props.padding, - horizontal_align: props.horizontalAlign, - vertical_align: props.verticalAlign, - transition: props.transition && intoApiTransition(props.transition), + width: style?.width, + height: style?.height, + background_color_rgba: style?.backgroundColor && intoApiRgbaColor(style?.backgroundColor), + tile_aspect_ratio: style?.tileAspectRatio, + margin: style?.margin, + padding: style?.padding, + horizontal_align: style?.horizontalAlign, + vertical_align: style?.verticalAlign, + transition: transition && intoApiTransition(transition), }; } diff --git a/ts/live-compositor/src/components/View.ts b/ts/live-compositor/src/components/View.ts index 5a7e3a8c9..0168795d6 100644 --- a/ts/live-compositor/src/components/View.ts +++ b/ts/live-compositor/src/components/View.ts @@ -1,12 +1,10 @@ -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component.js'; -import { intoApiRgbaColor, intoApiTransition, Transition } from './common.js'; +import type * as Api from '../api.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, sceneComponentIntoApi } from '../component.js'; +import type { Transition } from './common.js'; +import { intoApiRgbaColor, intoApiTransition } from './common.js'; -export type ViewProps = { - /** - * Id of a component. - */ - id?: Api.ComponentId; +export type ViewStyle = { /** * Width of a component in pixels. Exact behavior might be different based on the parent * component: @@ -55,11 +53,6 @@ export type ViewProps = { * absolutely positioned, instead of being laid out by its parent. */ rotation?: number; - /** - * Defines how this component will behave during a scene update. This will only have an - * effect if the previous scene already contained a `View` component with the same id. - */ - transition?: Transition; /** * (**default=`"hidden"`**) Controls what happens to content that is too big to fit into an area. */ @@ -70,28 +63,47 @@ export type ViewProps = { backgroundColor?: string; }; +export type ViewProps = { + /** + * Id of a component. + */ + id?: Api.ComponentId; + + /** + * Component styling properties. + */ + style?: ViewStyle; + + /** + * Defines how this component will behave during a scene update. This will only have an + * effect if the previous scene already contained a `View` component with the same id. + */ + transition?: Transition; +}; + const View = createCompositorComponent(sceneBuilder); -function sceneBuilder(props: ViewProps, children: SceneComponent[]): Api.Component { +function sceneBuilder( + { id, style = {}, transition }: ViewProps, + children: SceneComponent[] +): Api.Component { return { type: 'view', - + id, children: children.map(sceneComponentIntoApi), + width: style.width, + height: style.height, + direction: style.direction, - id: props.id, - width: props.width, - height: props.height, - direction: props.direction, - - top: props.top, - left: props.left, - bottom: props.bottom, - right: props.right, - rotation: props.rotation, + top: style.top, + right: style.right, + bottom: style.bottom, + left: style.left, - transition: props.transition && intoApiTransition(props.transition), - overflow: props.overflow, - background_color_rgba: props.backgroundColor && intoApiRgbaColor(props.backgroundColor), + rotation: style.rotation, + overflow: style.overflow, + background_color_rgba: style?.backgroundColor && intoApiRgbaColor(style.backgroundColor), + transition: transition && intoApiTransition(transition), }; } diff --git a/ts/live-compositor/src/components/WebView.ts b/ts/live-compositor/src/components/WebView.ts index d781c66a0..b0c61fcf5 100644 --- a/ts/live-compositor/src/components/WebView.ts +++ b/ts/live-compositor/src/components/WebView.ts @@ -1,5 +1,6 @@ -import * as Api from '../api.js'; -import { createCompositorComponent, SceneComponent, sceneComponentIntoApi } from '../component.js'; +import type * as Api from '../api.js'; +import type { SceneComponent } from '../component.js'; +import { createCompositorComponent, sceneComponentIntoApi } from '../component.js'; export type WebViewProps = { /** diff --git a/ts/live-compositor/src/components/common.ts b/ts/live-compositor/src/components/common.ts index 4678627a7..0df3635ac 100644 --- a/ts/live-compositor/src/components/common.ts +++ b/ts/live-compositor/src/components/common.ts @@ -1,4 +1,4 @@ -import * as Api from '../api.js'; +import type * as Api from '../api.js'; export interface Transition { /** diff --git a/ts/live-compositor/src/context/instanceContextStore.ts b/ts/live-compositor/src/context/instanceContextStore.ts index 1b24ab5b2..df64b6347 100644 --- a/ts/live-compositor/src/context/instanceContextStore.ts +++ b/ts/live-compositor/src/context/instanceContextStore.ts @@ -1,4 +1,4 @@ -import * as Api from '../api.js'; +import type * as Api from '../api.js'; export type StreamState = 'ready' | 'playing' | 'finished'; diff --git a/ts/live-compositor/src/context/outputContext.ts b/ts/live-compositor/src/context/outputContext.ts index 7aedb18bd..3f188e48d 100644 --- a/ts/live-compositor/src/context/outputContext.ts +++ b/ts/live-compositor/src/context/outputContext.ts @@ -1,4 +1,4 @@ -import { AudioInputsConfiguration } from '../types/registerOutput.js'; +import type { AudioInputsConfiguration } from '../types/registerOutput.js'; export type ContextAudioOptions = { volume: number; diff --git a/ts/live-compositor/src/hooks.ts b/ts/live-compositor/src/hooks.ts index 370fa7226..49bff0df5 100644 --- a/ts/live-compositor/src/hooks.ts +++ b/ts/live-compositor/src/hooks.ts @@ -1,8 +1,8 @@ import { useContext, useEffect, useSyncExternalStore } from 'react'; -import * as Api from './api.js'; +import type * as Api from './api.js'; import { LiveCompositorContext } from './context/index.js'; -import { InputStreamInfo } from './context/instanceContextStore.js'; +import type { InputStreamInfo } from './context/instanceContextStore.js'; export function useInputStreams(): Record { const ctx = useContext(LiveCompositorContext); @@ -19,7 +19,7 @@ export type AudioOptions = { /** * Hook used to control audio configuration. If you already placing InputStream component - * you can use `mute` and `volume` props instead. + * you can use `muted` and `volume` props instead. */ export function useAudioInput(inputId: Api.InputId, audioOptions: AudioOptions) { const ctx = useContext(LiveCompositorContext); diff --git a/ts/live-compositor/src/index.ts b/ts/live-compositor/src/index.ts index 15bd4cbfc..73df9f7b1 100644 --- a/ts/live-compositor/src/index.ts +++ b/ts/live-compositor/src/index.ts @@ -10,8 +10,12 @@ import { EasingFunction, Transition } from './components/common.js'; import { useAudioInput, useInputStreams } from './hooks.js'; import { CompositorEvent, CompositorEventType } from './types/events.js'; -export { RegisterInput } from './types/registerInput.js'; -export { RegisterOutput } from './types/registerOutput.js'; +export { RegisterRtpInput, RegisterMp4Input } from './types/registerInput.js'; +export { + RegisterRtpOutput, + RegisterMp4Output, + RegisterCanvasOutput, +} from './types/registerOutput.js'; export * as Inputs from './types/registerInput.js'; export * as Outputs from './types/registerOutput.js'; diff --git a/ts/live-compositor/src/types/registerInput.ts b/ts/live-compositor/src/types/registerInput.ts index e0d0b38bb..77f049ac9 100644 --- a/ts/live-compositor/src/types/registerInput.ts +++ b/ts/live-compositor/src/types/registerInput.ts @@ -1,8 +1,4 @@ -import * as Api from '../api.js'; - -export type RegisterInput = - | ({ type: 'rtp_stream' } & RegisterRtpInput) - | ({ type: 'mp4' } & RegisterMp4Input); +import type * as Api from '../api.js'; export type RegisterRtpInput = { /** diff --git a/ts/live-compositor/src/types/registerOutput.ts b/ts/live-compositor/src/types/registerOutput.ts index 620c9428e..977d9b77d 100644 --- a/ts/live-compositor/src/types/registerOutput.ts +++ b/ts/live-compositor/src/types/registerOutput.ts @@ -1,9 +1,5 @@ -import React from 'react'; -import * as Api from '../api.js'; - -export type RegisterOutput = - | ({ type: 'rtp_stream' } & RegisterRtpOutput) - | ({ type: 'mp4' } & RegisterMp4Output); +import type React from 'react'; +import type * as Api from '../api.js'; export type RegisterRtpOutput = { /** @@ -39,6 +35,10 @@ export type RegisterMp4Output = { audio?: Mp4AudioOptions; }; +export type RegisterCanvasOutput = { + video: OutputCanvasVideoOptions; +}; + export type RtpVideoOptions = { /** * Output resolution in pixels. @@ -73,6 +73,18 @@ export type Mp4VideoOptions = { root: React.ReactElement; }; +export type OutputCanvasVideoOptions = { + /** + * Output resolution in pixels. + */ + resolution: Api.Resolution; + /** + * HTMLCanvasElement + */ + canvas: any; + root: React.ReactElement; +}; + export type RtpVideoEncoderOptions = { type: 'ffmpeg_h264'; /** diff --git a/ts/live-compositor/src/types/registerRenderer.ts b/ts/live-compositor/src/types/registerRenderer.ts index 72b5ed030..3aca9afea 100644 --- a/ts/live-compositor/src/types/registerRenderer.ts +++ b/ts/live-compositor/src/types/registerRenderer.ts @@ -1,4 +1,4 @@ -import * as Api from '../api.js'; +import type * as Api from '../api.js'; export type RegisterShader = Api.ShaderSpec; diff --git a/ts/live-compositor/tsconfig.json b/ts/live-compositor/tsconfig.json index 27edaeb17..c86bcad63 100644 --- a/ts/live-compositor/tsconfig.json +++ b/ts/live-compositor/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../tsconfig.base.json", + "extends": "../tsconfig.json", "compilerOptions": { "outDir": "esm" } diff --git a/ts/package-lock.json b/ts/package-lock.json deleted file mode 100644 index d69507e6a..000000000 --- a/ts/package-lock.json +++ /dev/null @@ -1,14168 +0,0 @@ -{ - "name": "live-compositor-workspace", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "live-compositor-workspace", - "version": "0.1.0", - "workspaces": [ - "live-compositor", - "@live-compositor/core", - "@live-compositor/node", - "@live-compositor/browser-render", - "examples/node-examples", - "examples/vite-browser-render", - "create-live-compositor", - "create-live-compositor/templates/node-minimal", - "create-live-compositor/templates/node-express-zustand" - ], - "devDependencies": { - "@eslint/plugin-kit": "^0.2.0", - "@typescript-eslint/eslint-plugin": "^7.16.0", - "@typescript-eslint/parser": "^7.18.0", - "concurrently": "^9.0.1", - "eslint": "^8.57.0", - "eslint-config-prettier": "^9.1.0", - "eslint-import-resolver-typescript": "^3.6.3", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^5.1.3", - "json-schema-to-typescript": "^15.0.1", - "lerna": "^8.1.8", - "prettier": "^3.3.2", - "typescript": "^5.5.3" - } - }, - "@live-compositor/browser-render": { - "version": "0.1.0-rc.4", - "license": "BUSL-1.1", - "devDependencies": { - "@rollup/plugin-typescript": "^11.1.6", - "rollup": "^4.21.2", - "rollup-plugin-copy": "^3.5.0", - "rollup-plugin-dts": "^6.1.1", - "wasm-pack": "^0.13.0" - }, - "peerDependencies": { - "live-compositor": "^0.1.0" - } - }, - "@live-compositor/core": { - "version": "0.1.0", - "license": "MIT", - "dependencies": { - "react-reconciler": "0.29.2" - }, - "devDependencies": { - "@types/react-reconciler": "0.28.8" - }, - "peerDependencies": { - "live-compositor": "^0.1.0" - } - }, - "@live-compositor/node": { - "version": "0.1.0", - "license": "MIT", - "dependencies": { - "@live-compositor/core": "^0.1.0", - "fs-extra": "^11.2.0", - "node-fetch": "^2.6.7", - "tar": "^7.4.3", - "uuid": "^10.0.0", - "ws": "^8.18.0" - }, - "devDependencies": { - "@types/fs-extra": "^11.0.4", - "@types/node": "^20.14.10", - "@types/node-fetch": "^2.6.11", - "@types/uuid": "^10.0.0", - "@types/ws": "^8.5.12" - } - }, - "@live-compositor/node/node_modules/chownr": { - "version": "3.0.0", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "@live-compositor/node/node_modules/minizlib": { - "version": "3.0.1", - "license": "MIT", - "dependencies": { - "minipass": "^7.0.4", - "rimraf": "^5.0.5" - }, - "engines": { - "node": ">= 18" - } - }, - "@live-compositor/node/node_modules/mkdirp": { - "version": "3.0.1", - "license": "MIT", - "bin": { - "mkdirp": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "@live-compositor/node/node_modules/rimraf": { - "version": "5.0.10", - "license": "ISC", - "dependencies": { - "glob": "^10.3.7" - }, - "bin": { - "rimraf": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "@live-compositor/node/node_modules/tar": { - "version": "7.4.3", - "license": "ISC", - "dependencies": { - "@isaacs/fs-minipass": "^4.0.0", - "chownr": "^3.0.0", - "minipass": "^7.1.2", - "minizlib": "^3.0.1", - "mkdirp": "^3.0.1", - "yallist": "^5.0.0" - }, - "engines": { - "node": ">=18" - } - }, - "@live-compositor/node/node_modules/yallist": { - "version": "5.0.0", - "license": "BlueOak-1.0.0", - "engines": { - "node": ">=18" - } - }, - "create-live-compositor": { - "version": "0.1.0", - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "fs-extra": "^11.2.0", - "prompts": "^2.4.2" - }, - "bin": { - "create-live-compositor": "dist/index.js" - }, - "devDependencies": { - "@types/fs-extra": "^11.0.4", - "@types/prompts": "^2.4.9" - } - }, - "create-live-compositor/templates/node-express-zustand": { - "name": "template-node-express-zustand", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@live-compositor/node": "^0.1.0", - "express": "^4.21.0", - "live-compositor": "^0.1.0", - "react": "^18.3.1", - "zustand": "4.5.5" - }, - "devDependencies": { - "@types/express": "^4.17.21", - "@types/node": "^20.14.10", - "@types/react": "^18.3.3", - "typescript": "^5.5.3" - } - }, - "create-live-compositor/templates/node-minimal": { - "name": "template-node-minimal", - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@live-compositor/node": "^0.1.0", - "live-compositor": "^0.1.0", - "react": "^18.3.1" - }, - "devDependencies": { - "@types/node": "^20.14.10", - "@types/react": "^18.3.3", - "typescript": "^5.5.3" - } - }, - "examples/node-examples": { - "version": "1.0.0", - "license": "MIT", - "dependencies": { - "@live-compositor/node": "^0.1.0", - "@types/fs-extra": "^11.0.4", - "@types/node": "^20.14.10", - "fs-extra": "^11.2.0", - "live-compositor": "^0.1.0", - "node-fetch": "^2.6.7", - "ts-node": "^10.9.2" - } - }, - "examples/vite-browser-render": { - "name": "example", - "version": "1.0.0", - "dependencies": { - "@live-compositor/browser-render": "^0.1.0-rc.4", - "mp4box": "^0.5.2", - "react": "^18.3.1", - "react-dom": "^18.3.1" - }, - "devDependencies": { - "@eslint/js": "^9.9.0", - "@types/react": "^18.3.3", - "@types/react-dom": "^18.3.0", - "@vitejs/plugin-react": "^4.3.1", - "eslint": "^9.9.0", - "eslint-plugin-react-hooks": "^5.1.0-rc.0", - "eslint-plugin-react-refresh": "^0.4.9", - "globals": "^15.9.0", - "typescript": "^5.5.3", - "typescript-eslint": "^8.0.1", - "vite": "^5.4.1", - "vite-plugin-static-copy": "^1.0.6" - } - }, - "examples/vite-browser-render/node_modules/@eslint/eslintrc": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "examples/vite-browser-render/node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "examples/vite-browser-render/node_modules/@eslint/js": { - "version": "9.12.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "examples/vite-browser-render/node_modules/@eslint/plugin-kit": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.1.0.tgz", - "integrity": "sha512-autAXT203ixhqei9xt+qkYOvY8l6LAFIdT2UXc/RPNeUVfqRF1BV94GTJyVPFKT8nFM6MyVJhjLj9E8JWvf5zQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "examples/vite-browser-render/node_modules/brace-expansion": { - "version": "1.1.11", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "examples/vite-browser-render/node_modules/eslint": { - "version": "9.10.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.11.0", - "@eslint/config-array": "^0.18.0", - "@eslint/eslintrc": "^3.1.0", - "@eslint/js": "9.10.0", - "@eslint/plugin-kit": "^0.1.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.3.0", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^8.0.2", - "eslint-visitor-keys": "^4.0.0", - "espree": "^10.1.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", - "is-path-inside": "^3.0.3", - "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", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "examples/vite-browser-render/node_modules/eslint-scope": { - "version": "8.1.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "examples/vite-browser-render/node_modules/eslint-visitor-keys": { - "version": "4.1.0", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "examples/vite-browser-render/node_modules/eslint/node_modules/@eslint/js": { - "version": "9.10.0", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "examples/vite-browser-render/node_modules/espree": { - "version": "10.2.0", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.12.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.1.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "examples/vite-browser-render/node_modules/file-entry-cache": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "examples/vite-browser-render/node_modules/flat-cache": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.4" - }, - "engines": { - "node": ">=16" - } - }, - "examples/vite-browser-render/node_modules/globals": { - "version": "15.11.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "examples/vite-browser-render/node_modules/minimatch": { - "version": "3.1.2", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "live-compositor": { - "version": "0.1.0", - "license": "MIT", - "devDependencies": { - "@types/react": "^18.3.3" - }, - "peerDependencies": { - "react": "*" - } - }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@apidevtools/json-schema-ref-parser": { - "version": "11.7.0", - "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-11.7.0.tgz", - "integrity": "sha512-pRrmXMCwnmrkS3MLgAIW5dXRzeTv6GLjkjb4HmxNnvAKXN1Nfzp4KmGADBQvlVUcqi+a5D+hfGDLLnd5NnYxog==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jsdevtools/ono": "^7.1.3", - "@types/json-schema": "^7.0.15", - "js-yaml": "^4.1.0" - }, - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://github.com/sponsors/philsturgeon" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.25.7.tgz", - "integrity": "sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.25.7", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.25.7.tgz", - "integrity": "sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.25.7.tgz", - "integrity": "sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.0", - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/helper-compilation-targets": "^7.25.7", - "@babel/helper-module-transforms": "^7.25.7", - "@babel/helpers": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.25.7.tgz", - "integrity": "sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.7", - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25", - "jsesc": "^3.0.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz", - "integrity": "sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/compat-data": "^7.25.7", - "@babel/helper-validator-option": "^7.25.7", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^3.0.2" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/@babel/helper-module-imports": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz", - "integrity": "sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz", - "integrity": "sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-module-imports": "^7.25.7", - "@babel/helper-simple-access": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "@babel/traverse": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz", - "integrity": "sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz", - "integrity": "sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/traverse": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz", - "integrity": "sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz", - "integrity": "sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-option": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz", - "integrity": "sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.25.7.tgz", - "integrity": "sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.25.7.tgz", - "integrity": "sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.7", - "chalk": "^2.4.2", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@babel/highlight/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.25.7.tgz", - "integrity": "sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.25.7" - }, - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-self": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.25.7.tgz", - "integrity": "sha512-JD9MUnLbPL0WdVK8AWC7F7tTG2OS6u/AKKnsK+NdRhUiVdnzyR1S3kKQCaRLOiaULvUiqK6Z4JQE635VgtCFeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-transform-react-jsx-source": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.25.7.tgz", - "integrity": "sha512-S/JXG/KrbIY06iyJPKfxr0qRxnhNOdkNXYBl/rmwgDd72cQLH9tEGkDm/yJPGvcSIUoikzfjMios9i+xT/uv9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/template": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.7.tgz", - "integrity": "sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/types": "^7.25.7" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.25.7.tgz", - "integrity": "sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.25.7", - "@babel/generator": "^7.25.7", - "@babel/parser": "^7.25.7", - "@babel/template": "^7.25.7", - "@babel/types": "^7.25.7", - "debug": "^4.3.1", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.25.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.25.7.tgz", - "integrity": "sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/helper-string-parser": "^7.25.7", - "@babel/helper-validator-identifier": "^7.25.7", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@cspotcode/source-map-support/node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@emnapi/core": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.3.0.tgz", - "integrity": "sha512-9hRqVlhwqBqCoToZ3hFcNVqL+uyHV06Y47ax4UB8L6XgVRqYz7MFnfessojo6+5TK89pKwJnpophwjTMOeKI9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@emnapi/wasi-threads": "1.0.1", - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.0.tgz", - "integrity": "sha512-XMBySMuNZs3DM96xcJmLW4EfGnf+uGmFNjzpehMjuX5PLB5j87ar2Zc4e3PVeZ3I5g3tYtAqskB28manlF69Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.1.tgz", - "integrity": "sha512-iIBu7mwkq4UQGeMEM8bLwNK962nXdhodeScX4slfQnRhEMMzvYivHhutCIk8uojvmASXXPC2WNEjwxFWk72Oqw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", - "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", - "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", - "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", - "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", - "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", - "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", - "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", - "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", - "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", - "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", - "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", - "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", - "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", - "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", - "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", - "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", - "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", - "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", - "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", - "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", - "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", - "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", - "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "license": "MIT", - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.11.1.tgz", - "integrity": "sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/config-array": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.18.0.tgz", - "integrity": "sha512-fTxvnS1sRMu3+JjXwJG0j/i4RT9u4qJ+lqS/yCGap4lH4zZGzQ7tu+xZqQmcMZq5OBZDL4QRxQzRjkWcGt8IVw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.4", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", - "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.4.tgz", - "integrity": "sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@eslint/plugin-kit": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.0.tgz", - "integrity": "sha512-vH9PiIMMwvhCx31Af3HiGzsVNULDbyVkHXwlemn/B0TFj/00ho3y55efXrUZTfQipxoHC5u4xq6zblww1zm1Ig==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "levn": "^0.4.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", - "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", - "deprecated": "Use @eslint/config-array instead", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.3", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", - "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@hutson/parse-repository-url": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", - "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "license": "ISC", - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/string-locale-compare": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@isaacs/string-locale-compare/-/string-locale-compare-1.1.0.tgz", - "integrity": "sha512-SQ7Kzhh9+D+ZW9MA0zkYv3VXhIDNx+LzM6EJ+/65I3QY+enU6Itte7E5XX7EWrqLW2FN4n06GWzBnPoC3th2aQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/set-array": "^1.2.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.24" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/set-array": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", - "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==", - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.25", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", - "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsdevtools/ono": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", - "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@lerna/create": { - "version": "8.1.8", - "resolved": "https://registry.npmjs.org/@lerna/create/-/create-8.1.8.tgz", - "integrity": "sha512-wi72R01tgjBjzG2kjRyTHl4yCTKDfDMIXRyKz9E/FBa9SkFvUOAE4bdyY9MhEsRZmSWL7+CYE8Flv/HScRpBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@npmcli/arborist": "7.5.4", - "@npmcli/package-json": "5.2.0", - "@npmcli/run-script": "8.1.0", - "@nx/devkit": ">=17.1.2 < 20", - "@octokit/plugin-enterprise-rest": "6.0.1", - "@octokit/rest": "19.0.11", - "aproba": "2.0.0", - "byte-size": "8.1.1", - "chalk": "4.1.0", - "clone-deep": "4.0.1", - "cmd-shim": "6.0.3", - "color-support": "1.1.3", - "columnify": "1.6.0", - "console-control-strings": "^1.1.0", - "conventional-changelog-core": "5.0.1", - "conventional-recommended-bump": "7.0.1", - "cosmiconfig": "^8.2.0", - "dedent": "1.5.3", - "execa": "5.0.0", - "fs-extra": "^11.2.0", - "get-stream": "6.0.0", - "git-url-parse": "14.0.0", - "glob-parent": "6.0.2", - "globby": "11.1.0", - "graceful-fs": "4.2.11", - "has-unicode": "2.0.1", - "ini": "^1.3.8", - "init-package-json": "6.0.3", - "inquirer": "^8.2.4", - "is-ci": "3.0.1", - "is-stream": "2.0.0", - "js-yaml": "4.1.0", - "libnpmpublish": "9.0.9", - "load-json-file": "6.2.0", - "lodash": "^4.17.21", - "make-dir": "4.0.0", - "minimatch": "3.0.5", - "multimatch": "5.0.0", - "node-fetch": "2.6.7", - "npm-package-arg": "11.0.2", - "npm-packlist": "8.0.2", - "npm-registry-fetch": "^17.1.0", - "nx": ">=17.1.2 < 20", - "p-map": "4.0.0", - "p-map-series": "2.1.0", - "p-queue": "6.6.2", - "p-reduce": "^2.1.0", - "pacote": "^18.0.6", - "pify": "5.0.0", - "read-cmd-shim": "4.0.0", - "resolve-from": "5.0.0", - "rimraf": "^4.4.1", - "semver": "^7.3.4", - "set-blocking": "^2.0.0", - "signal-exit": "3.0.7", - "slash": "^3.0.0", - "ssri": "^10.0.6", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "strong-log-transformer": "2.1.0", - "tar": "6.2.1", - "temp-dir": "1.0.0", - "upath": "2.0.1", - "uuid": "^10.0.0", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "5.0.1", - "wide-align": "1.1.5", - "write-file-atomic": "5.0.1", - "write-pkg": "4.0.0", - "yargs": "17.7.2", - "yargs-parser": "21.1.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@lerna/create/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@lerna/create/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@lerna/create/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@lerna/create/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@lerna/create/node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@lerna/create/node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@lerna/create/node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@lerna/create/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/@lerna/create/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@lerna/create/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@lerna/create/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@lerna/create/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@lerna/create/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@live-compositor/browser-render": { - "resolved": "@live-compositor/browser-render", - "link": true - }, - "node_modules/@live-compositor/core": { - "resolved": "@live-compositor/core", - "link": true - }, - "node_modules/@live-compositor/node": { - "resolved": "@live-compositor/node", - "link": true - }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", - "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@emnapi/core": "^1.1.0", - "@emnapi/runtime": "^1.1.0", - "@tybys/wasm-util": "^0.9.0" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, - "node_modules/@npmcli/agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-2.2.2.tgz", - "integrity": "sha512-OrcNPXdpSl9UX7qPVRWbmWMCSXrcDa2M9DvrbOTj7ao1S4PlqVFYv9/yLKMkrJKZ/V5A/kDBC690or307i26Og==", - "dev": true, - "license": "ISC", - "dependencies": { - "agent-base": "^7.1.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "lru-cache": "^10.0.1", - "socks-proxy-agent": "^8.0.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/arborist": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/@npmcli/arborist/-/arborist-7.5.4.tgz", - "integrity": "sha512-nWtIc6QwwoUORCRNzKx4ypHqCk3drI+5aeYdMTQQiRCcn4lOOgfQh7WyZobGYTxXPSq1VwV53lkpN/BRlRk08g==", - "dev": true, - "license": "ISC", - "dependencies": { - "@isaacs/string-locale-compare": "^1.1.0", - "@npmcli/fs": "^3.1.1", - "@npmcli/installed-package-contents": "^2.1.0", - "@npmcli/map-workspaces": "^3.0.2", - "@npmcli/metavuln-calculator": "^7.1.1", - "@npmcli/name-from-folder": "^2.0.0", - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.1.0", - "@npmcli/query": "^3.1.0", - "@npmcli/redact": "^2.0.0", - "@npmcli/run-script": "^8.1.0", - "bin-links": "^4.0.4", - "cacache": "^18.0.3", - "common-ancestor-path": "^1.0.1", - "hosted-git-info": "^7.0.2", - "json-parse-even-better-errors": "^3.0.2", - "json-stringify-nice": "^1.1.4", - "lru-cache": "^10.2.2", - "minimatch": "^9.0.4", - "nopt": "^7.2.1", - "npm-install-checks": "^6.2.0", - "npm-package-arg": "^11.0.2", - "npm-pick-manifest": "^9.0.1", - "npm-registry-fetch": "^17.0.1", - "pacote": "^18.0.6", - "parse-conflict-json": "^3.0.0", - "proc-log": "^4.2.0", - "proggy": "^2.0.0", - "promise-all-reject-late": "^1.0.0", - "promise-call-limit": "^3.0.1", - "read-package-json-fast": "^3.0.2", - "semver": "^7.3.7", - "ssri": "^10.0.6", - "treeverse": "^3.0.0", - "walk-up-path": "^3.0.1" - }, - "bin": { - "arborist": "bin/index.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-3.1.1.tgz", - "integrity": "sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==", - "dev": true, - "license": "ISC", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-5.0.8.tgz", - "integrity": "sha512-liASfw5cqhjNW9UFd+ruwwdEf/lbOAQjLL2XY2dFW/bkJheXDYZgOyul/4gVvEV4BWkTXjYGmDqMw9uegdbJNQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/promise-spawn": "^7.0.0", - "ini": "^4.1.3", - "lru-cache": "^10.0.1", - "npm-pick-manifest": "^9.0.0", - "proc-log": "^4.0.0", - "promise-inflight": "^1.0.1", - "promise-retry": "^2.0.1", - "semver": "^7.3.5", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/ini": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", - "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/git/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/git/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/installed-package-contents": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", - "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-bundled": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "bin": { - "installed-package-contents": "bin/index.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/map-workspaces": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", - "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/name-from-folder": "^2.0.0", - "glob": "^10.2.2", - "minimatch": "^9.0.0", - "read-package-json-fast": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/metavuln-calculator": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/metavuln-calculator/-/metavuln-calculator-7.1.1.tgz", - "integrity": "sha512-Nkxf96V0lAx3HCpVda7Vw4P23RILgdi/5K1fmj2tZkWIYLpXAN8k2UVVOsW16TsS5F8Ws2I7Cm+PU1/rsVF47g==", - "dev": true, - "license": "ISC", - "dependencies": { - "cacache": "^18.0.0", - "json-parse-even-better-errors": "^3.0.0", - "pacote": "^18.0.0", - "proc-log": "^4.1.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/name-from-folder": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", - "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/node-gyp": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz", - "integrity": "sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/package-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-5.2.0.tgz", - "integrity": "sha512-qe/kiqqkW0AGtvBjL8TJKZk/eBBSpnJkUWvHdQ9jM2lKHXRYYJuyNpJPlJw3c8QjC2ow6NZYiLExhUaeJelbxQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "glob": "^10.2.2", - "hosted-git-info": "^7.0.0", - "json-parse-even-better-errors": "^3.0.0", - "normalize-package-data": "^6.0.0", - "proc-log": "^4.0.0", - "semver": "^7.5.3" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-7.0.2.tgz", - "integrity": "sha512-xhfYPXoV5Dy4UkY0D+v2KkwvnDfiA/8Mt3sWCGI/hM03NsYIH8ZaG6QzS9x7pje5vHZBZJ2v6VRFVTWACnqcmQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/promise-spawn/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/promise-spawn/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/query": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/query/-/query-3.1.0.tgz", - "integrity": "sha512-C/iR0tk7KSKGldibYIB9x8GtO/0Bd0I2mhOaDb8ucQL/bQVTmGoeREaFj64Z5+iCBRf3dQfed0CjJL7I8iTkiQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "postcss-selector-parser": "^6.0.10" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/redact": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-2.0.1.tgz", - "integrity": "sha512-YgsR5jCQZhVmTJvjduTOIHph0L73pK8xwMVaDY0PatySqVM9AZj93jpoXYSJqfHFxFkN9dmqTw6OiqExsS3LPw==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-8.1.0.tgz", - "integrity": "sha512-y7efHHwghQfk28G2z3tlZ67pLG0XdfYbcVG26r7YIXALRsrVQcTq4/tdenSmdOrEsNahIYA/eh8aEVROWGFUDg==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/node-gyp": "^3.0.0", - "@npmcli/package-json": "^5.0.0", - "@npmcli/promise-spawn": "^7.0.0", - "node-gyp": "^10.0.0", - "proc-log": "^4.0.0", - "which": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@npmcli/run-script/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/@npmcli/run-script/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/@nrwl/devkit": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nrwl/devkit/-/devkit-19.8.4.tgz", - "integrity": "sha512-OoIqDjj2mWzLs3aSF6w5OiC2xywYi/jBxHc7t7Lyi56Vc4dQq8vJMELa9WtG6qH0k05fF7N+jAoKlfvLgbbEFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nx/devkit": "19.8.4" - } - }, - "node_modules/@nrwl/tao": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nrwl/tao/-/tao-19.8.4.tgz", - "integrity": "sha512-03/+QZ4/6HmKbEmvzCutLI1XIclBspNYtiVHmGPRWuwhnZViqYfnyl8J7RWVdFEoKKA5fhJqpg7e28aGuoMBvQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "nx": "19.8.4", - "tslib": "^2.3.0" - }, - "bin": { - "tao": "index.js" - } - }, - "node_modules/@nx/devkit": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/devkit/-/devkit-19.8.4.tgz", - "integrity": "sha512-FPFT8gVDFRSEmU0n7nRkT4Rnqy7OMznfPXLfDZtVuzEi5Cl6ftG3UBUvCgJcJFCYJVAZAUuv6vRSRarHd51XFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nrwl/devkit": "19.8.4", - "ejs": "^3.1.7", - "enquirer": "~2.3.6", - "ignore": "^5.0.4", - "minimatch": "9.0.3", - "semver": "^7.5.3", - "tmp": "~0.2.1", - "tslib": "^2.3.0", - "yargs-parser": "21.1.1" - }, - "peerDependencies": { - "nx": ">= 17 <= 20" - } - }, - "node_modules/@nx/devkit/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@nx/nx-darwin-arm64": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-arm64/-/nx-darwin-arm64-19.8.4.tgz", - "integrity": "sha512-mbSGt63hYcVCSQ54kpHl0lFqr5CsbkGJ4L3liWE30Da7vXZJwUBr9f+b9DnQ64IZzlu6vAhNcaiYQXa9lAk0yQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-darwin-x64": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-darwin-x64/-/nx-darwin-x64-19.8.4.tgz", - "integrity": "sha512-lTcXUCXNvqHdLmrNCOyDF+u6pDx209Ew7nSR47sQPvkycIHYi0gvgk0yndFn1Swah0lP4OxWg7rzAfmOlZd6ew==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-freebsd-x64": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-freebsd-x64/-/nx-freebsd-x64-19.8.4.tgz", - "integrity": "sha512-4BUplOxPZeUwlUNfzHHMmebNVgDFW/jNX6TWRS+jINwOHnpWLkLFAXu27G80/S3OaniVCzEQklXO9b+1UsdgXw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-linux-arm-gnueabihf": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-19.8.4.tgz", - "integrity": "sha512-Wahul8oz9huEm/Jv3wud5IGWdZxkGG4tdJm9i5TV5wxfUMAWbKU9v2nzZZins452UYESWvwvDkiuBPZqSto3qw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-linux-arm64-gnu": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-19.8.4.tgz", - "integrity": "sha512-L0RVCZkNAtZDplLT7uJV7M9cXxq2Fxw+8ex3eb9XSp7eyLeFO21T0R6vTouJ42E/PEvGApCAcyGqtnyPNMZFfw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-linux-arm64-musl": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-19.8.4.tgz", - "integrity": "sha512-0q8r8I8WCsY3xowDI2j109SCUSkFns/BJ40aCfRh9hhrtaIIc5qXUw2YFTjxUZNcRJXx9j9+hTe9jBkUSIGvCw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-linux-x64-gnu": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-19.8.4.tgz", - "integrity": "sha512-XcRBNe0ws7KB0PMcUlpQqzzjjxMP8VdqirBz7CfB2XQ8xKmP3370p0cDvqs/4oKDHK4PCkmvVFX60tzakutylA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-linux-x64-musl": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-19.8.4.tgz", - "integrity": "sha512-JB4tAuZBCF0yqSnKF3pHXa0b7LA3ebi3Bw08QmMr//ON4aU+eXURGBuj9XvULD2prY+gpBrvf+MsG1XJAHL6Zg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-win32-arm64-msvc": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-19.8.4.tgz", - "integrity": "sha512-WvQag/pN9ofRWRDvOZxj3jvJoTetlvV1uyirnDrhupRgi+Fj67OlGGt2zVUHaXFGEa1MfCEG6Vhk6152m4KyaQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@nx/nx-win32-x64-msvc": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-19.8.4.tgz", - "integrity": "sha512-//JntLrN3L7WL/WgP3D0FE34caYTPcG/GIMBguC9w7YDyTlEikLgLbobjdCPz+2f9OWGvIZbJgGmtHNjnETM/g==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10" - } - }, - "node_modules/@octokit/auth-token": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-3.0.4.tgz", - "integrity": "sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/core": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-4.2.4.tgz", - "integrity": "sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/auth-token": "^3.0.0", - "@octokit/graphql": "^5.0.0", - "@octokit/request": "^6.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/endpoint": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-7.0.6.tgz", - "integrity": "sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/graphql": { - "version": "5.0.6", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-5.0.6.tgz", - "integrity": "sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/request": "^6.0.0", - "@octokit/types": "^9.0.0", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "18.1.1", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.1.1.tgz", - "integrity": "sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-enterprise-rest": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz", - "integrity": "sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz", - "integrity": "sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/tsconfig": "^1.0.2", - "@octokit/types": "^9.2.3" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=4" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz", - "integrity": "sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^10.0.0" - }, - "engines": { - "node": ">= 14" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-10.0.0.tgz", - "integrity": "sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^18.0.0" - } - }, - "node_modules/@octokit/request": { - "version": "6.2.8", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-6.2.8.tgz", - "integrity": "sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/endpoint": "^7.0.0", - "@octokit/request-error": "^3.0.0", - "@octokit/types": "^9.0.0", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/request-error": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-3.0.3.tgz", - "integrity": "sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/types": "^9.0.0", - "deprecation": "^2.0.0", - "once": "^1.4.0" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/rest": { - "version": "19.0.11", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.11.tgz", - "integrity": "sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/core": "^4.2.1", - "@octokit/plugin-paginate-rest": "^6.1.2", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^7.1.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/@octokit/tsconfig": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@octokit/tsconfig/-/tsconfig-1.0.2.tgz", - "integrity": "sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@octokit/types": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-9.3.2.tgz", - "integrity": "sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@octokit/openapi-types": "^18.0.0" - } - }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=14" - } - }, - "node_modules/@pkgr/core": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", - "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/@rollup/plugin-typescript": { - "version": "11.1.6", - "resolved": "https://registry.npmjs.org/@rollup/plugin-typescript/-/plugin-typescript-11.1.6.tgz", - "integrity": "sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rollup/pluginutils": "^5.1.0", - "resolve": "^1.22.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^2.14.0||^3.0.0||^4.0.0", - "tslib": "*", - "typescript": ">=3.7.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - }, - "tslib": { - "optional": true - } - } - }, - "node_modules/@rollup/pluginutils": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.2.tgz", - "integrity": "sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.0", - "estree-walker": "^2.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=14.0.0" - }, - "peerDependencies": { - "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" - }, - "peerDependenciesMeta": { - "rollup": { - "optional": true - } - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz", - "integrity": "sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz", - "integrity": "sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz", - "integrity": "sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz", - "integrity": "sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz", - "integrity": "sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz", - "integrity": "sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz", - "integrity": "sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz", - "integrity": "sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz", - "integrity": "sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz", - "integrity": "sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz", - "integrity": "sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz", - "integrity": "sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz", - "integrity": "sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz", - "integrity": "sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz", - "integrity": "sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz", - "integrity": "sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sigstore/bundle": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-2.3.2.tgz", - "integrity": "sha512-wueKWDk70QixNLB363yHc2D2ItTgYiMTdPwK8D9dKQMR3ZQ0c35IxP5xnwQ8cNLoCgCRcHf14kE+CLIvNX1zmA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/core": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-1.1.0.tgz", - "integrity": "sha512-JzBqdVIyqm2FRQCulY6nbQzMpJJpSiJ8XXWMhtOX9eKgaXXpfNOF53lzQEjIydlStnd/eFtuC1dW4VYdD93oRg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/protobuf-specs": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.3.2.tgz", - "integrity": "sha512-c6B0ehIWxMI8wiS/bj6rHMPqeFvngFV7cDU/MY+B16P9Z3Mp9k8L93eYZ7BYzSickzuqAQqAq0V956b3Ju6mLw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/sign": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-2.3.2.tgz", - "integrity": "sha512-5Vz5dPVuunIIvC5vBb0APwo7qKA4G9yM48kPWJT+OEERs40md5GoUR1yedwpekWZ4m0Hhw44m6zU+ObsON+iDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "make-fetch-happen": "^13.0.1", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/tuf": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-2.3.4.tgz", - "integrity": "sha512-44vtsveTPUpqhm9NCrbU8CWLe3Vck2HO1PNLw7RIajbB7xhtn5RBPm1VNSCMwqGYHhDsBJG8gDF0q4lgydsJvw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/protobuf-specs": "^0.3.2", - "tuf-js": "^2.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sigstore/verify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-1.2.1.tgz", - "integrity": "sha512-8iKx79/F73DKbGfRf7+t4dqrc0bRr0thdPrxAtCKWRm/F0tG71i6O1rvlnScncJLLBZHn3h8M3c1BSUAb9yu8g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.1.0", - "@sigstore/protobuf-specs": "^0.3.2" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.11.tgz", - "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==", - "license": "MIT" - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "license": "MIT" - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "license": "MIT" - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "license": "MIT" - }, - "node_modules/@tufjs/canonical-json": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", - "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@tufjs/models": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-2.0.1.tgz", - "integrity": "sha512-92F7/SFyufn4DXsha9+QfKnN03JGqtMFMXgSHbZOo8JG59WkTni7UzAouNQDf7AuP9OAMxVOPQcqG3sB7w+kkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tufjs/canonical-json": "2.0.0", - "minimatch": "^9.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@types/babel__core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.20.7", - "@babel/types": "^7.20.7", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__template": { - "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.20.7" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.5", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", - "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.21.tgz", - "integrity": "sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-11.0.4.tgz", - "integrity": "sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==", - "license": "MIT", - "dependencies": { - "@types/jsonfile": "*", - "@types/node": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", - "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/jsonfile": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/@types/jsonfile/-/jsonfile-6.1.4.tgz", - "integrity": "sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.17.10", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-YpS0zzoduEhuOWjAotS6A5AVCva7X4lVlYLF0FYHAY9sdraBfnatttHItlWeZdGhuEkf+OzMNg2ZYAx8t+52uQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "20.16.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.11.tgz", - "integrity": "sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw==", - "license": "MIT", - "dependencies": { - "undici-types": "~6.19.2" - } - }, - "node_modules/@types/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-24xFj9R5+rfQJLRyM56qh+wnVSYhyXC2tkoBndtY0U+vubqNsYXGjufB2nn8Q6gt0LrARwL6UBtMCSVCwl4B1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "form-data": "^4.0.0" - } - }, - "node_modules/@types/normalize-package-data": { - "version": "2.4.4", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", - "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/prompts": { - "version": "2.4.9", - "resolved": "https://registry.npmjs.org/@types/prompts/-/prompts-2.4.9.tgz", - "integrity": "sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "kleur": "^3.0.3" - } - }, - "node_modules/@types/prop-types": { - "version": "15.7.13", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.13.tgz", - "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/@types/qs": { - "version": "6.9.16", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.16.tgz", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/react": { - "version": "18.3.11", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.11.tgz", - "integrity": "sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@types/prop-types": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.3.0", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz", - "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-reconciler": { - "version": "0.28.8", - "resolved": "https://registry.npmjs.org/@types/react-reconciler/-/react-reconciler-0.28.8.tgz", - "integrity": "sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/send": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", - "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.15.7", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", - "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/ws": { - "version": "8.5.12", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", - "integrity": "sha512-3tPRkv1EtkDpzlgyKyI8pGsGZAGPEaXeu0DOj5DI25Ja91bdAYddYHbADRYVrZMRbfW+1l5YwXVDKohDJNQxkQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.18.0.tgz", - "integrity": "sha512-94EQTWZ40mzBc42ATNIBimBEDltSJ9RQHCC8vc/PDbxi4k8dVwUAv4o98dk50M1zB+JGFxp43FP7f8+FP8R6Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/type-utils": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.18.0.tgz", - "integrity": "sha512-4Z+L8I2OqhZV8qA132M4wNL30ypZGYOQVBfMgxDH/K5UX0PNqTu1c6za9ST5r9+tavvHiTWmBnKzpCJ/GlVFtg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.18.0.tgz", - "integrity": "sha512-jjhdIE/FPF2B7Z1uzc6i3oWKbGcHb87Qw7AWj6jmEqNOfDFbJWtjt/XfwCpvNkpGWlcJaog5vTR+VV8+w9JflA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.18.0.tgz", - "integrity": "sha512-XL0FJXuCLaDuX2sYqZUUSOJ2sG5/i1AAze+axqmLnSkNEVMVYLF+cbwlB2w8D1tinFuSikHmFta+P+HOofrLeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "7.18.0", - "@typescript-eslint/utils": "7.18.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.18.0.tgz", - "integrity": "sha512-iZqi+Ds1y4EDYUtlOOC+aUmxnE9xS/yCigkjA7XpTKV6nCBd3Hp/PRGGmdwnfkV2ThMyYldP1wRpm/id99spTQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.18.0.tgz", - "integrity": "sha512-aP1v/BSPnnyhMHts8cf1qQ6Q1IFwwRvAQGRvBFkWlo3/lH29OXA3Pts+c10nxRxIBrDnoMqzhgdwVe5f2D6OzA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/visitor-keys": "7.18.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.18.0.tgz", - "integrity": "sha512-kK0/rNa2j74XuHVcoCZxdFBMF+aq/vH83CXAOHieC+2Gis4mF8jJXT5eAfyD3K0sAxtPuwxaIOIOvhwzVDt/kw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "7.18.0", - "@typescript-eslint/types": "7.18.0", - "@typescript-eslint/typescript-estree": "7.18.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.18.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.18.0.tgz", - "integrity": "sha512-cDF0/Gf81QpY3xYyJKDV14Zwdmid5+uuENhjH2EqFaF0ni+yAyq/LzMaIJdhNJXZI7uLzwIlA+V7oWoyn6Curg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "7.18.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/@vitejs/plugin-react": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.3.2.tgz", - "integrity": "sha512-hieu+o05v4glEBucTcKMK3dlES0OeJlD9YVOAPraVMOInBCwzumaIFiUjr4bHK7NPgnAHgiskUoceKercrN8vg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/core": "^7.25.2", - "@babel/plugin-transform-react-jsx-self": "^7.24.7", - "@babel/plugin-transform-react-jsx-source": "^7.24.7", - "@types/babel__core": "^7.20.5", - "react-refresh": "^0.14.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "peerDependencies": { - "vite": "^4.2.0 || ^5.0.0" - } - }, - "node_modules/@yarnpkg/lockfile": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", - "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/@yarnpkg/parsers": { - "version": "3.0.0-rc.46", - "resolved": "https://registry.npmjs.org/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz", - "integrity": "sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "js-yaml": "^3.10.0", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/@yarnpkg/parsers/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@yarnpkg/parsers/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@yarnpkg/parsers/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@zkochan/js-yaml": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/@zkochan/js-yaml/-/js-yaml-0.0.7.tgz", - "integrity": "sha512-nrUSn7hzt7J6JWgWGz78ZYI8wj+gdIJdk0Ynjpp8l+trkn58Uqsf6RYrYkEK+3X18EX+TNdtJI0WxAtc+L84SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/abbrev": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", - "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.12.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.1.tgz", - "integrity": "sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==", - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "license": "MIT", - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/add-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", - "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/agent-base": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", - "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", - "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "license": "MIT" - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/array-buffer-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", - "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "is-array-buffer": "^3.0.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "license": "MIT" - }, - "node_modules/array-ify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", - "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", - "dev": true, - "license": "MIT" - }, - "node_modules/array-includes": { - "version": "3.1.8", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", - "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0", - "get-intrinsic": "^1.2.4", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", - "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", - "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arraybuffer.prototype.slice": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", - "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "es-abstract": "^1.22.3", - "es-errors": "^1.2.1", - "get-intrinsic": "^1.2.3", - "is-array-buffer": "^3.0.4", - "is-shared-array-buffer": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/async": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", - "dev": true, - "license": "MIT" - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/available-typed-arrays": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", - "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/axios": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", - "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.15.6", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/bin-links": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", - "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", - "dev": true, - "license": "ISC", - "dependencies": { - "cmd-shim": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "read-cmd-shim": "^4.0.0", - "write-file-atomic": "^5.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/binary-install": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/binary-install/-/binary-install-1.1.0.tgz", - "integrity": "sha512-rkwNGW+3aQVSZoD0/o3mfPN6Yxh3Id0R/xzTVBVVpGNlVz8EGwusksxRlbk/A5iKTZt9zkMn3qIqmAt3vpfbzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "axios": "^0.26.1", - "rimraf": "^3.0.2", - "tar": "^6.1.11" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/binary-install/node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.24.0.tgz", - "integrity": "sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "caniuse-lite": "^1.0.30001663", - "electron-to-chromium": "^1.5.28", - "node-releases": "^2.0.18", - "update-browserslist-db": "^1.1.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/byte-size": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-8.1.1.tgz", - "integrity": "sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.17" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cacache": { - "version": "18.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-18.0.4.tgz", - "integrity": "sha512-B+L5iIa9mgcjLbliir2th36yEwPftrzteHYujzsx3dFP/31GCHcIeS8f5MGd80odLOjaOvSpU3EEAmRQptkxLQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/fs": "^3.1.0", - "fs-minipass": "^3.0.0", - "glob": "^10.2.2", - "lru-cache": "^10.0.1", - "minipass": "^7.0.3", - "minipass-collect": "^2.0.1", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "p-map": "^4.0.0", - "ssri": "^10.0.0", - "tar": "^6.1.11", - "unique-filename": "^3.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001667", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz", - "integrity": "sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true, - "license": "MIT" - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/ci-info": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", - "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-width": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", - "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/cliui/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/cliui/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cliui/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-deep/node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/cmd-shim": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", - "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/colorette": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz", - "integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==", - "dev": true, - "license": "MIT" - }, - "node_modules/columnify": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.6.0.tgz", - "integrity": "sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "strip-ansi": "^6.0.1", - "wcwidth": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/common-ancestor-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/common-ancestor-path/-/common-ancestor-path-1.0.1.tgz", - "integrity": "sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==", - "dev": true, - "license": "ISC" - }, - "node_modules/compare-func": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", - "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-ify": "^1.0.0", - "dot-prop": "^5.1.0" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/concurrently": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-9.0.1.tgz", - "integrity": "sha512-wYKvCd/f54sTXJMSfV6Ln/B8UrfLBKOYa+lzc6CHay3Qek+LorVSBdMVfyewFhRbH0Rbabsk4D+3PL/VjQ5gzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.2", - "lodash": "^4.17.21", - "rxjs": "^7.8.1", - "shell-quote": "^1.8.1", - "supports-color": "^8.1.1", - "tree-kill": "^1.2.2", - "yargs": "^17.7.2" - }, - "bin": { - "conc": "dist/bin/concurrently.js", - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/open-cli-tools/concurrently?sponsor=1" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "compare-func": "^2.0.0" - }, - "engines": { - "node": ">=16" - } - }, - "node_modules/conventional-changelog-core": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz", - "integrity": "sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "add-stream": "^1.0.0", - "conventional-changelog-writer": "^6.0.0", - "conventional-commits-parser": "^4.0.0", - "dateformat": "^3.0.3", - "get-pkg-repo": "^4.2.1", - "git-raw-commits": "^3.0.0", - "git-remote-origin-url": "^2.0.0", - "git-semver-tags": "^5.0.0", - "normalize-package-data": "^3.0.3", - "read-pkg": "^3.0.0", - "read-pkg-up": "^3.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-core/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-core/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/conventional-changelog-preset-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz", - "integrity": "sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-changelog-writer": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz", - "integrity": "sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "conventional-commits-filter": "^3.0.0", - "dateformat": "^3.0.3", - "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^8.1.2", - "semver": "^7.0.0", - "split": "^1.0.1" - }, - "bin": { - "conventional-changelog-writer": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-commits-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz", - "integrity": "sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash.ismatch": "^4.4.0", - "modify-values": "^1.0.1" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-commits-parser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz", - "integrity": "sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-text-path": "^1.0.1", - "JSONStream": "^1.3.5", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "conventional-commits-parser": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/conventional-recommended-bump": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz", - "integrity": "sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==", - "dev": true, - "license": "MIT", - "dependencies": { - "concat-stream": "^2.0.0", - "conventional-changelog-preset-loader": "^3.0.0", - "conventional-commits-filter": "^3.0.0", - "conventional-commits-parser": "^4.0.0", - "git-raw-commits": "^3.0.0", - "git-semver-tags": "^5.0.0", - "meow": "^8.1.2" - }, - "bin": { - "conventional-recommended-bump": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", - "license": "MIT" - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cosmiconfig": { - "version": "8.3.6", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", - "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0", - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/create-live-compositor": { - "resolved": "create-live-compositor", - "link": true - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true, - "license": "MIT", - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/csstype": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", - "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", - "devOptional": true, - "license": "MIT" - }, - "node_modules/dargs": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", - "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/data-view-buffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", - "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", - "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/data-view-byte-offset": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", - "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-data-view": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/dateformat": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", - "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/debug": { - "version": "4.3.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", - "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decamelize-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", - "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", - "dev": true, - "license": "MIT", - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/dedent": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", - "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "babel-plugin-macros": "^3.1.0" - }, - "peerDependenciesMeta": { - "babel-plugin-macros": { - "optional": true - } - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/defaults": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", - "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", - "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.0.1", - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dotenv-expand": { - "version": "11.0.6", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-11.0.6.tgz", - "integrity": "sha512-8NHi73otpWsZGBSZwwknTXS5pqMOrk9+Ssrna8xCaxkzEpU9OTf9R5ArQGVw03//Zmk9MOwLPng9WwndvpAJ5g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dotenv": "^16.4.4" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true, - "license": "MIT" - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "license": "MIT" - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "license": "MIT" - }, - "node_modules/ejs": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", - "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.5.35", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.35.tgz", - "integrity": "sha512-hOSRInrIDm0Brzp4IHW2F/VM+638qOL2CzE0DgpnGzKW27C95IqqeqgKz/hxHGnvPxvQGpHUGD5qRVC9EZY2+A==", - "dev": true, - "license": "ISC" - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "license": "MIT" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/encoding/node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.17.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz", - "integrity": "sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/enquirer": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", - "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-colors": "^4.1.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/envinfo": { - "version": "7.13.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", - "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true, - "license": "MIT" - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-abstract": { - "version": "1.23.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-buffer-byte-length": "^1.0.1", - "arraybuffer.prototype.slice": "^1.0.3", - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "data-view-buffer": "^1.0.1", - "data-view-byte-length": "^1.0.1", - "data-view-byte-offset": "^1.0.0", - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-set-tostringtag": "^2.0.3", - "es-to-primitive": "^1.2.1", - "function.prototype.name": "^1.1.6", - "get-intrinsic": "^1.2.4", - "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2", - "has-proto": "^1.0.3", - "has-symbols": "^1.0.3", - "hasown": "^2.0.2", - "internal-slot": "^1.0.7", - "is-array-buffer": "^3.0.4", - "is-callable": "^1.2.7", - "is-data-view": "^1.0.1", - "is-negative-zero": "^2.0.3", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.3", - "is-string": "^1.0.7", - "is-typed-array": "^1.1.13", - "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", - "object-keys": "^1.1.1", - "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", - "safe-array-concat": "^1.1.2", - "safe-regex-test": "^1.0.3", - "string.prototype.trim": "^1.2.9", - "string.prototype.trimend": "^1.0.8", - "string.prototype.trimstart": "^1.0.8", - "typed-array-buffer": "^1.0.2", - "typed-array-byte-length": "^1.0.1", - "typed-array-byte-offset": "^1.0.2", - "typed-array-length": "^1.0.6", - "unbox-primitive": "^1.0.2", - "which-typed-array": "^1.1.15" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-object-atoms": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", - "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-set-tostringtag": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", - "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4", - "has-tostringtag": "^1.0.2", - "hasown": "^2.0.1" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", - "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.0" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/esbuild": { - "version": "0.21.5", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", - "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.21.5", - "@esbuild/android-arm": "0.21.5", - "@esbuild/android-arm64": "0.21.5", - "@esbuild/android-x64": "0.21.5", - "@esbuild/darwin-arm64": "0.21.5", - "@esbuild/darwin-x64": "0.21.5", - "@esbuild/freebsd-arm64": "0.21.5", - "@esbuild/freebsd-x64": "0.21.5", - "@esbuild/linux-arm": "0.21.5", - "@esbuild/linux-arm64": "0.21.5", - "@esbuild/linux-ia32": "0.21.5", - "@esbuild/linux-loong64": "0.21.5", - "@esbuild/linux-mips64el": "0.21.5", - "@esbuild/linux-ppc64": "0.21.5", - "@esbuild/linux-riscv64": "0.21.5", - "@esbuild/linux-s390x": "0.21.5", - "@esbuild/linux-x64": "0.21.5", - "@esbuild/netbsd-x64": "0.21.5", - "@esbuild/openbsd-x64": "0.21.5", - "@esbuild/sunos-x64": "0.21.5", - "@esbuild/win32-arm64": "0.21.5", - "@esbuild/win32-ia32": "0.21.5", - "@esbuild/win32-x64": "0.21.5" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "license": "MIT" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", - "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", - "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.1", - "@humanwhocodes/config-array": "^0.13.0", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-prettier": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz", - "integrity": "sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==", - "dev": true, - "license": "MIT", - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "3.6.3", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.3.tgz", - "integrity": "sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.3.5", - "enhanced-resolve": "^5.15.0", - "eslint-module-utils": "^2.8.1", - "fast-glob": "^3.3.2", - "get-tsconfig": "^4.7.5", - "is-bun-module": "^1.0.2", - "is-glob": "^4.0.3" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*", - "eslint-plugin-import-x": "*" - }, - "peerDependenciesMeta": { - "eslint-plugin-import": { - "optional": true - }, - "eslint-plugin-import-x": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", - "hasown": "^2.0.2", - "is-core-module": "^2.15.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.8", - "object.groupby": "^1.0.3", - "object.values": "^1.2.0", - "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" - } - }, - "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz", - "integrity": "sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "prettier-linter-helpers": "^1.0.0", - "synckit": "^0.9.1" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint-plugin-prettier" - }, - "peerDependencies": { - "@types/eslint": ">=8.0.0", - "eslint": ">=8.0.0", - "eslint-config-prettier": "*", - "prettier": ">=3.0.0" - }, - "peerDependenciesMeta": { - "@types/eslint": { - "optional": true - }, - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "5.1.0-rc-fb9a90fa48-20240614", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.1.0-rc-fb9a90fa48-20240614.tgz", - "integrity": "sha512-xsiRwaDNF5wWNC4ZHLut+x/YcAxksUd9Rizt7LaEn3bV8VyYRpXnRJQlLOfYaVy9esk4DFP4zPPnoNVjq5Gc0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" - } - }, - "node_modules/eslint-plugin-react-refresh": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.12.tgz", - "integrity": "sha512-9neVjoGv20FwYtCP6CB1dzR1vr57ZDNOXst21wd2xJ/cTlM2xLq0GWVlSNTdMn/4BtP6cHYBMCSp1wFBJ9jBsg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "eslint": ">=7" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true, - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estree-walker": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", - "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, - "node_modules/example": { - "resolved": "examples/vite-browser-render", - "link": true - }, - "node_modules/execa": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", - "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/exponential-backoff": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz", - "integrity": "sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/express": { - "version": "4.21.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.1.tgz", - "integrity": "sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==", - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.3", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.10", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/external-editor/node_modules/tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-diff": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", - "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true, - "license": "MIT" - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/figures": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", - "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/figures/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "license": "MIT", - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true, - "license": "ISC" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-each": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", - "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-callable": "^1.1.3" - } - }, - "node_modules/foreground-child": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.0.tgz", - "integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==", - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/front-matter": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/front-matter/-/front-matter-4.0.2.tgz", - "integrity": "sha512-I8ZuJ/qG92NWX8i5x1Y8qyj3vizhXS31OxjKDu3LKP+7/qBgfIKValiZIEwoVoJKUHlhWtYrktkxV1XsX+pPlg==", - "dev": true, - "license": "MIT", - "dependencies": { - "js-yaml": "^3.13.1" - } - }, - "node_modules/front-matter/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/front-matter/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/front-matter/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "license": "MIT" - }, - "node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/fs-minipass": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", - "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true, - "license": "ISC" - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/function.prototype.name": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", - "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.2.0", - "es-abstract": "^1.22.1", - "functions-have-names": "^1.2.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functions-have-names": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", - "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true, - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-pkg-repo": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", - "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@hutson/parse-repository-url": "^3.0.0", - "hosted-git-info": "^4.0.0", - "through2": "^2.0.0", - "yargs": "^16.2.0" - }, - "bin": { - "get-pkg-repo": "src/cli.js" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/get-pkg-repo/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/get-pkg-repo/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/get-pkg-repo/node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-pkg-repo/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-pkg-repo/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/get-pkg-repo/node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/get-pkg-repo/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/get-pkg-repo/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/get-port": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz", - "integrity": "sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-stream": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", - "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", - "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-tsconfig": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.8.1.tgz", - "integrity": "sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-pkg-maps": "^1.0.0" - }, - "funding": { - "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" - } - }, - "node_modules/git-raw-commits": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-3.0.0.tgz", - "integrity": "sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "dargs": "^7.0.0", - "meow": "^8.1.2", - "split2": "^3.2.2" - }, - "bin": { - "git-raw-commits": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/git-remote-origin-url": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", - "integrity": "sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "gitconfiglocal": "^1.0.0", - "pify": "^2.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/git-remote-origin-url/node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/git-semver-tags": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-5.0.1.tgz", - "integrity": "sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==", - "dev": true, - "license": "MIT", - "dependencies": { - "meow": "^8.1.2", - "semver": "^7.0.0" - }, - "bin": { - "git-semver-tags": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/git-up": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/git-up/-/git-up-7.0.0.tgz", - "integrity": "sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-ssh": "^1.4.0", - "parse-url": "^8.1.0" - } - }, - "node_modules/git-url-parse": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/git-url-parse/-/git-url-parse-14.0.0.tgz", - "integrity": "sha512-NnLweV+2A4nCvn4U/m2AoYu0pPKlsmhK9cknG7IMwsjFY1S2jxM+mAhsDxyxfCIGfGaD+dozsyX4b6vkYc83yQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "git-up": "^7.0.0" - } - }, - "node_modules/gitconfiglocal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", - "integrity": "sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==", - "dev": true, - "license": "BSD", - "dependencies": { - "ini": "^1.3.2" - } - }, - "node_modules/glob": { - "version": "10.4.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", - "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", - "license": "ISC", - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", - "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "license": "ISC" - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, - "node_modules/handlebars": { - "version": "4.7.8", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", - "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.5", - "neo-async": "^2.6.2", - "source-map": "^0.6.1", - "wordwrap": "^1.0.0" - }, - "bin": { - "handlebars": "bin/handlebars" - }, - "engines": { - "node": ">=0.4.7" - }, - "optionalDependencies": { - "uglify-js": "^3.1.4" - } - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", - "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hosted-git-info": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-7.0.2.tgz", - "integrity": "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^10.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "license": "MIT", - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.5.tgz", - "integrity": "sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/ignore-walk": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", - "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", - "dev": true, - "license": "ISC", - "dependencies": { - "minimatch": "^9.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", - "dev": true, - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true, - "license": "ISC" - }, - "node_modules/init-package-json": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-6.0.3.tgz", - "integrity": "sha512-Zfeb5ol+H+eqJWHTaGca9BovufyGeIfr4zaaBorPmJBMrJ+KBnN+kQx2ZtXdsotUTgldHmHQV44xvUWOUA7E2w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/package-json": "^5.0.0", - "npm-package-arg": "^11.0.0", - "promzard": "^1.0.0", - "read": "^3.0.1", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/inquirer": { - "version": "8.2.6", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", - "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^6.0.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/inquirer/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/internal-slot": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", - "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "hasown": "^2.0.0", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/is-array-buffer": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", - "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-boolean-object": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", - "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-bun-module": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-bun-module/-/is-bun-module-1.2.1.tgz", - "integrity": "sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.6.3" - } - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-view": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", - "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-date-object": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", - "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/is-negative-zero": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", - "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-path-inside": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", - "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", - "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ssh": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/is-ssh/-/is-ssh-1.4.0.tgz", - "integrity": "sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "protocols": "^2.0.1" - } - }, - "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-text-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", - "integrity": "sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==", - "dev": true, - "license": "MIT", - "dependencies": { - "text-extensions": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typed-array": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", - "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "which-typed-array": "^1.1.14" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-weakref": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", - "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "license": "BlueOak-1.0.0", - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, - "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.4", - "minimatch": "^3.1.2" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/jest-diff": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", - "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^29.6.3", - "jest-get-type": "^29.6.3", - "pretty-format": "^29.7.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", - "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "license": "MIT" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsesc": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", - "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", - "dev": true, - "license": "MIT", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", - "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/json-schema-to-typescript": { - "version": "15.0.2", - "resolved": "https://registry.npmjs.org/json-schema-to-typescript/-/json-schema-to-typescript-15.0.2.tgz", - "integrity": "sha512-+cRBw+bBJ3k783mZroDIgz1pLNPB4hvj6nnbHTWwEVl0dkW8qdZ+M9jWhBb+Y0FAdHvNsXACga3lewGO8lktrw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@apidevtools/json-schema-ref-parser": "^11.5.5", - "@types/json-schema": "^7.0.15", - "@types/lodash": "^4.17.7", - "glob": "^10.3.12", - "is-glob": "^4.0.3", - "js-yaml": "^4.1.0", - "lodash": "^4.17.21", - "minimist": "^1.2.8", - "prettier": "^3.2.5" - }, - "bin": { - "json2ts": "dist/src/cli.js" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-stringify-nice": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/json-stringify-nice/-/json-stringify-nice-1.1.4.tgz", - "integrity": "sha512-5Z5RFW63yxReJ7vANgW6eZFGWaQvnPE3WNmZoOJrSkGju2etKA2L5rrOa1sm877TVTFt57A80BH1bArcmlLfPw==", - "dev": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true, - "license": "ISC" - }, - "node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true, - "license": "MIT" - }, - "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ], - "license": "MIT" - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, - "node_modules/just-diff": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/just-diff/-/just-diff-6.0.2.tgz", - "integrity": "sha512-S59eriX5u3/QhMNq3v/gm8Kd0w8OS6Tz2FS1NG4blv+z0MuQcBRJyFWjdovM0Rad4/P4aUPFtnkNjMjyMlMSYA==", - "dev": true, - "license": "MIT" - }, - "node_modules/just-diff-apply": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/just-diff-apply/-/just-diff-apply-5.5.0.tgz", - "integrity": "sha512-OYTthRfSh55WOItVqwpefPtNt2VdKsq5AnAK6apdtR6yCH8pr0CmSr710J0Mf+WdQy7K/OzMy7K2MgAfdQURDw==", - "dev": true, - "license": "MIT" - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/lerna": { - "version": "8.1.8", - "resolved": "https://registry.npmjs.org/lerna/-/lerna-8.1.8.tgz", - "integrity": "sha512-Rmo5ShMx73xM2CUcRixjmpZIXB7ZFlWEul1YvJyx/rH4onAwDHtUGD7Rx4NZYL8QSRiQHroglM2Oyq+WqA4BYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@lerna/create": "8.1.8", - "@npmcli/arborist": "7.5.4", - "@npmcli/package-json": "5.2.0", - "@npmcli/run-script": "8.1.0", - "@nx/devkit": ">=17.1.2 < 20", - "@octokit/plugin-enterprise-rest": "6.0.1", - "@octokit/rest": "19.0.11", - "aproba": "2.0.0", - "byte-size": "8.1.1", - "chalk": "4.1.0", - "clone-deep": "4.0.1", - "cmd-shim": "6.0.3", - "color-support": "1.1.3", - "columnify": "1.6.0", - "console-control-strings": "^1.1.0", - "conventional-changelog-angular": "7.0.0", - "conventional-changelog-core": "5.0.1", - "conventional-recommended-bump": "7.0.1", - "cosmiconfig": "^8.2.0", - "dedent": "1.5.3", - "envinfo": "7.13.0", - "execa": "5.0.0", - "fs-extra": "^11.2.0", - "get-port": "5.1.1", - "get-stream": "6.0.0", - "git-url-parse": "14.0.0", - "glob-parent": "6.0.2", - "globby": "11.1.0", - "graceful-fs": "4.2.11", - "has-unicode": "2.0.1", - "import-local": "3.1.0", - "ini": "^1.3.8", - "init-package-json": "6.0.3", - "inquirer": "^8.2.4", - "is-ci": "3.0.1", - "is-stream": "2.0.0", - "jest-diff": ">=29.4.3 < 30", - "js-yaml": "4.1.0", - "libnpmaccess": "8.0.6", - "libnpmpublish": "9.0.9", - "load-json-file": "6.2.0", - "lodash": "^4.17.21", - "make-dir": "4.0.0", - "minimatch": "3.0.5", - "multimatch": "5.0.0", - "node-fetch": "2.6.7", - "npm-package-arg": "11.0.2", - "npm-packlist": "8.0.2", - "npm-registry-fetch": "^17.1.0", - "nx": ">=17.1.2 < 20", - "p-map": "4.0.0", - "p-map-series": "2.1.0", - "p-pipe": "3.1.0", - "p-queue": "6.6.2", - "p-reduce": "2.1.0", - "p-waterfall": "2.1.1", - "pacote": "^18.0.6", - "pify": "5.0.0", - "read-cmd-shim": "4.0.0", - "resolve-from": "5.0.0", - "rimraf": "^4.4.1", - "semver": "^7.3.8", - "set-blocking": "^2.0.0", - "signal-exit": "3.0.7", - "slash": "3.0.0", - "ssri": "^10.0.6", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "strong-log-transformer": "2.1.0", - "tar": "6.2.1", - "temp-dir": "1.0.0", - "typescript": ">=3 < 6", - "upath": "2.0.1", - "uuid": "^10.0.0", - "validate-npm-package-license": "3.0.4", - "validate-npm-package-name": "5.0.1", - "wide-align": "1.1.5", - "write-file-atomic": "5.0.1", - "write-pkg": "4.0.0", - "yargs": "17.7.2", - "yargs-parser": "21.1.1" - }, - "bin": { - "lerna": "dist/cli.js" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/lerna/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/lerna/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/lerna/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/lerna/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/lerna/node_modules/glob/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/lerna/node_modules/glob/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/lerna/node_modules/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/lerna/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/lerna/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lerna/node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/lerna/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/lerna/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/lerna/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/libnpmaccess": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-8.0.6.tgz", - "integrity": "sha512-uM8DHDEfYG6G5gVivVl+yQd4pH3uRclHC59lzIbSvy7b5FEwR+mU49Zq1jEyRtRFv7+M99mUW9S0wL/4laT4lw==", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/libnpmpublish": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-9.0.9.tgz", - "integrity": "sha512-26zzwoBNAvX9AWOPiqqF6FG4HrSCPsHFkQm7nT+xU1ggAujL/eae81RnCv4CJ2In9q9fh10B88sYSzKCUh/Ghg==", - "dev": true, - "license": "ISC", - "dependencies": { - "ci-info": "^4.0.0", - "normalize-package-data": "^6.0.1", - "npm-package-arg": "^11.0.2", - "npm-registry-fetch": "^17.0.1", - "proc-log": "^4.2.0", - "semver": "^7.3.7", - "sigstore": "^2.2.0", - "ssri": "^10.0.6" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/libnpmpublish/node_modules/ci-info": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", - "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/sibiraj-s" - } - ], - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lines-and-columns": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.3.tgz", - "integrity": "sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - } - }, - "node_modules/live-compositor": { - "resolved": "live-compositor", - "link": true - }, - "node_modules/load-json-file": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-6.2.0.tgz", - "integrity": "sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.15", - "parse-json": "^5.0.0", - "strip-bom": "^4.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/load-json-file/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.ismatch": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", - "integrity": "sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==", - "dev": true, - "license": "MIT" - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "license": "ISC" - }, - "node_modules/magic-string": { - "version": "0.30.11", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", - "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" - } - }, - "node_modules/make-dir": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", - "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", - "dev": true, - "license": "MIT", - "dependencies": { - "semver": "^7.5.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "license": "ISC" - }, - "node_modules/make-fetch-happen": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-13.0.1.tgz", - "integrity": "sha512-cKTUFc/rbKUd/9meOvgrpJ2WrNzymt6jfRDdwg5UCnVzv9dTpEj9JS5m3wtziXVCjluIXyL8pcaukYqezIzZQA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/agent": "^2.0.0", - "cacache": "^18.0.0", - "http-cache-semantics": "^4.1.1", - "is-lambda": "^1.0.1", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "proc-log": "^4.2.0", - "promise-retry": "^2.0.1", - "ssri": "^10.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/meow": { - "version": "8.1.2", - "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", - "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/meow/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=8" - } - }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/meow/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimist-options": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "license": "MIT", - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-collect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", - "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, - "node_modules/minipass-fetch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", - "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^7.0.3", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-pipeline/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minizlib/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/modify-values": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", - "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/mp4box": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/mp4box/-/mp4box-0.5.2.tgz", - "integrity": "sha512-zRmGlvxy+YdW3Dmt+TR4xPHynbxwXtAQDTN/Fo9N3LMxaUlB2C5KmZpzYyGKy4c7k4Jf3RCR0A2pm9SZELOLXw==", - "license": "BSD-3-Clause" - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "license": "MIT" - }, - "node_modules/multimatch": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-5.0.0.tgz", - "integrity": "sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/multimatch/node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/multimatch/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/multimatch/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true, - "license": "ISC" - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true, - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-examples": { - "resolved": "examples/node-examples", - "link": true - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-gyp": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-10.2.0.tgz", - "integrity": "sha512-sp3FonBAaFe4aYTcFdZUn2NYkbP7xroPGYvQmP4Nl5PxamznItBnNCgjrVTKrEfQynInMsJvZrdmqUnysCJ8rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^10.3.10", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^13.0.0", - "nopt": "^7.0.0", - "proc-log": "^4.1.0", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^4.0.0" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/node-gyp/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16" - } - }, - "node_modules/node-gyp/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, - "node_modules/node-machine-id": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/node-machine-id/-/node-machine-id-1.1.12.tgz", - "integrity": "sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/node-releases": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", - "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==", - "dev": true, - "license": "MIT" - }, - "node_modules/nopt": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", - "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", - "dev": true, - "license": "ISC", - "dependencies": { - "abbrev": "^2.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/normalize-package-data": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-6.0.2.tgz", - "integrity": "sha512-V6gygoYb/5EmNI+MEGrWkC+e6+Rr7mTmfHrxDbLzxQogBkgzo76rkok0Am6thgSF7Mv2nLOajAJj5vDJZEFn7g==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^7.0.0", - "semver": "^7.3.5", - "validate-npm-package-license": "^3.0.4" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/npm-bundled": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-3.0.1.tgz", - "integrity": "sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-install-checks": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-6.3.0.tgz", - "integrity": "sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "semver": "^7.1.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-normalize-package-bin": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", - "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-package-arg": { - "version": "11.0.2", - "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.2.tgz", - "integrity": "sha512-IGN0IAwmhDJwy13Wc8k+4PEbTPhpJnMtfR53ZbOyjkvmEcLS4nCwp6mvMWjS5sUjeiW3mpx6cHmuhKEu9XmcQw==", - "dev": true, - "license": "ISC", - "dependencies": { - "hosted-git-info": "^7.0.0", - "proc-log": "^4.0.0", - "semver": "^7.3.5", - "validate-npm-package-name": "^5.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-packlist": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-8.0.2.tgz", - "integrity": "sha512-shYrPFIS/JLP4oQmAwDyk5HcyysKW8/JLTEA32S0Z5TzvpaeeX2yMFfoK1fjEBnCBvVyIB/Jj/GBFdm0wsgzbA==", - "dev": true, - "license": "ISC", - "dependencies": { - "ignore-walk": "^6.0.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/npm-pick-manifest": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-9.1.0.tgz", - "integrity": "sha512-nkc+3pIIhqHVQr085X9d2JzPzLyjzQS96zbruppqC9aZRm/x8xx6xhI98gHtsfELP2bE+loHq8ZaHFHhe+NauA==", - "dev": true, - "license": "ISC", - "dependencies": { - "npm-install-checks": "^6.0.0", - "npm-normalize-package-bin": "^3.0.0", - "npm-package-arg": "^11.0.0", - "semver": "^7.3.5" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-registry-fetch": { - "version": "17.1.0", - "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-17.1.0.tgz", - "integrity": "sha512-5+bKQRH0J1xG1uZ1zMNvxW0VEyoNWgJpY9UDuluPFLKDfJ9u2JmmjmTJV1srBGQOROfdBMiVvnH2Zvpbm+xkVA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/redact": "^2.0.0", - "jsonparse": "^1.3.1", - "make-fetch-happen": "^13.0.0", - "minipass": "^7.0.2", - "minipass-fetch": "^3.0.0", - "minizlib": "^2.1.2", - "npm-package-arg": "^11.0.0", - "proc-log": "^4.0.0" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nx": { - "version": "19.8.4", - "resolved": "https://registry.npmjs.org/nx/-/nx-19.8.4.tgz", - "integrity": "sha512-fc833c3UKo6kuoG4z0kSKet17yWym3VzcQ+yPWYspxxxd8GFVVk42+9wieyVQDi9YqtKZQ6PdQfSEPm59/M7SA==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@napi-rs/wasm-runtime": "0.2.4", - "@nrwl/tao": "19.8.4", - "@yarnpkg/lockfile": "^1.1.0", - "@yarnpkg/parsers": "3.0.0-rc.46", - "@zkochan/js-yaml": "0.0.7", - "axios": "^1.7.4", - "chalk": "^4.1.0", - "cli-cursor": "3.1.0", - "cli-spinners": "2.6.1", - "cliui": "^8.0.1", - "dotenv": "~16.4.5", - "dotenv-expand": "~11.0.6", - "enquirer": "~2.3.6", - "figures": "3.2.0", - "flat": "^5.0.2", - "front-matter": "^4.0.2", - "ignore": "^5.0.4", - "jest-diff": "^29.4.1", - "jsonc-parser": "3.2.0", - "lines-and-columns": "2.0.3", - "minimatch": "9.0.3", - "node-machine-id": "1.1.12", - "npm-run-path": "^4.0.1", - "open": "^8.4.0", - "ora": "5.3.0", - "semver": "^7.5.3", - "string-width": "^4.2.3", - "strong-log-transformer": "^2.1.0", - "tar-stream": "~2.2.0", - "tmp": "~0.2.1", - "tsconfig-paths": "^4.1.2", - "tslib": "^2.3.0", - "yargs": "^17.6.2", - "yargs-parser": "21.1.1" - }, - "bin": { - "nx": "bin/nx.js", - "nx-cloud": "bin/nx-cloud.js" - }, - "optionalDependencies": { - "@nx/nx-darwin-arm64": "19.8.4", - "@nx/nx-darwin-x64": "19.8.4", - "@nx/nx-freebsd-x64": "19.8.4", - "@nx/nx-linux-arm-gnueabihf": "19.8.4", - "@nx/nx-linux-arm64-gnu": "19.8.4", - "@nx/nx-linux-arm64-musl": "19.8.4", - "@nx/nx-linux-x64-gnu": "19.8.4", - "@nx/nx-linux-x64-musl": "19.8.4", - "@nx/nx-win32-arm64-msvc": "19.8.4", - "@nx/nx-win32-x64-msvc": "19.8.4" - }, - "peerDependencies": { - "@swc-node/register": "^1.8.0", - "@swc/core": "^1.3.85" - }, - "peerDependenciesMeta": { - "@swc-node/register": { - "optional": true - }, - "@swc/core": { - "optional": true - } - } - }, - "node_modules/nx/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/nx/node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/nx/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/nx/node_modules/ora": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.3.0.tgz", - "integrity": "sha512-zAKMgGXUim0Jyd6CXK9lraBnD3H5yPGBPPOkC23a2BG6hsm4Zu6OQSjQuEtV0BHDf4aKHcUFvJiGRrFuW3MG8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "log-symbols": "^4.0.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nx/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nx/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/nx/node_modules/tsconfig-paths": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz", - "integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.assign": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", - "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.5", - "define-properties": "^1.2.1", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", - "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.values": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", - "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", - "integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/optionator": { - "version": "0.9.4", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", - "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.5" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map-series": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-2.1.0.tgz", - "integrity": "sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-pipe": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-3.1.0.tgz", - "integrity": "sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-reduce": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-2.1.0.tgz", - "integrity": "sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/p-waterfall": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-2.1.1.tgz", - "integrity": "sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-reduce": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "license": "BlueOak-1.0.0" - }, - "node_modules/pacote": { - "version": "18.0.6", - "resolved": "https://registry.npmjs.org/pacote/-/pacote-18.0.6.tgz", - "integrity": "sha512-+eK3G27SMwsB8kLIuj4h1FUhHtwiEUo21Tw8wNjmvdlpOEr613edv+8FUsTj/4F/VN5ywGE19X18N7CC2EJk6A==", - "dev": true, - "license": "ISC", - "dependencies": { - "@npmcli/git": "^5.0.0", - "@npmcli/installed-package-contents": "^2.0.1", - "@npmcli/package-json": "^5.1.0", - "@npmcli/promise-spawn": "^7.0.0", - "@npmcli/run-script": "^8.0.0", - "cacache": "^18.0.0", - "fs-minipass": "^3.0.0", - "minipass": "^7.0.2", - "npm-package-arg": "^11.0.0", - "npm-packlist": "^8.0.0", - "npm-pick-manifest": "^9.0.0", - "npm-registry-fetch": "^17.0.0", - "proc-log": "^4.0.0", - "promise-retry": "^2.0.1", - "sigstore": "^2.2.0", - "ssri": "^10.0.0", - "tar": "^6.1.11" - }, - "bin": { - "pacote": "bin/index.js" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-conflict-json": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/parse-conflict-json/-/parse-conflict-json-3.0.1.tgz", - "integrity": "sha512-01TvEktc68vwbJOtWZluyWeVGWjP+bZwXtPDMQVbBKzbJ/vZBif0L69KH1+cHv1SZ6e0FKLvjyHe8mqsIqYOmw==", - "dev": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "just-diff": "^6.0.0", - "just-diff-apply": "^5.2.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse-json/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-json/node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true, - "license": "MIT" - }, - "node_modules/parse-path": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", - "integrity": "sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog==", - "dev": true, - "license": "MIT", - "dependencies": { - "protocols": "^2.0.0" - } - }, - "node_modules/parse-url": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/parse-url/-/parse-url-8.1.0.tgz", - "integrity": "sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==", - "dev": true, - "license": "MIT", - "dependencies": { - "parse-path": "^7.0.0" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-to-regexp": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.10.tgz", - "integrity": "sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==", - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.0.tgz", - "integrity": "sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz", - "integrity": "sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-dir/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-dir/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/postcss": { - "version": "8.4.47", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.47.tgz", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.1.0", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-selector-parser": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz", - "integrity": "sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==", - "dev": true, - "license": "MIT", - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.3.tgz", - "integrity": "sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==", - "dev": true, - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/proc-log": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-4.2.0.tgz", - "integrity": "sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/proggy": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proggy/-/proggy-2.0.0.tgz", - "integrity": "sha512-69agxLtnI8xBs9gUGqEnK26UfiexpHy+KUpBQWabiytQjnn5wFY8rklAi7GRfABIuPNnQ/ik48+LGLkYYJcy4A==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/promise-all-reject-late": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-all-reject-late/-/promise-all-reject-late-1.0.1.tgz", - "integrity": "sha512-vuf0Lf0lOxyQREH7GDIOUMLS7kz+gs8i6B+Yi8dC68a2sychGrHTJYghMBD6k7eUcH0H5P73EckCA48xijWqXw==", - "dev": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/promise-call-limit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/promise-call-limit/-/promise-call-limit-3.0.2.tgz", - "integrity": "sha512-mRPQO2T1QQVw11E7+UdCJu7S61eJVWknzml9sC1heAdj1jxl0fWMBypIt9ZOcLFf8FkG995ZD7RnVk7HH72fZw==", - "dev": true, - "license": "ISC", - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "dev": true, - "license": "ISC" - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "license": "MIT", - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/promzard": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/promzard/-/promzard-1.0.2.tgz", - "integrity": "sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "read": "^3.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/protocols": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/protocols/-/protocols-2.0.1.tgz", - "integrity": "sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true, - "license": "MIT" - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", - "license": "MIT", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/react": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", - "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", - "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-is": { - "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", - "dev": true, - "license": "MIT" - }, - "node_modules/react-reconciler": { - "version": "0.29.2", - "resolved": "https://registry.npmjs.org/react-reconciler/-/react-reconciler-0.29.2.tgz", - "integrity": "sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.2" - }, - "engines": { - "node": ">=0.10.0" - }, - "peerDependencies": { - "react": "^18.3.1" - } - }, - "node_modules/react-refresh": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", - "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/read": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/read/-/read-3.0.1.tgz", - "integrity": "sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==", - "dev": true, - "license": "ISC", - "dependencies": { - "mute-stream": "^1.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-cmd-shim": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz", - "integrity": "sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-package-json-fast": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", - "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", - "dev": true, - "license": "ISC", - "dependencies": { - "json-parse-even-better-errors": "^3.0.0", - "npm-normalize-package-bin": "^3.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true, - "license": "ISC" - }, - "node_modules/read-pkg/node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "license": "MIT", - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/read-pkg/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/read/node_modules/mute-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", - "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/redent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "license": "MIT", - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz", - "integrity": "sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-errors": "^1.3.0", - "set-function-name": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-cwd/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-pkg-maps": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", - "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/restore-cursor/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/rollup": { - "version": "4.24.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.0.tgz", - "integrity": "sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "1.0.6" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.0", - "@rollup/rollup-android-arm64": "4.24.0", - "@rollup/rollup-darwin-arm64": "4.24.0", - "@rollup/rollup-darwin-x64": "4.24.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.0", - "@rollup/rollup-linux-arm-musleabihf": "4.24.0", - "@rollup/rollup-linux-arm64-gnu": "4.24.0", - "@rollup/rollup-linux-arm64-musl": "4.24.0", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.0", - "@rollup/rollup-linux-riscv64-gnu": "4.24.0", - "@rollup/rollup-linux-s390x-gnu": "4.24.0", - "@rollup/rollup-linux-x64-gnu": "4.24.0", - "@rollup/rollup-linux-x64-musl": "4.24.0", - "@rollup/rollup-win32-arm64-msvc": "4.24.0", - "@rollup/rollup-win32-ia32-msvc": "4.24.0", - "@rollup/rollup-win32-x64-msvc": "4.24.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/rollup-plugin-copy": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/rollup-plugin-copy/-/rollup-plugin-copy-3.5.0.tgz", - "integrity": "sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/fs-extra": "^8.0.1", - "colorette": "^1.1.0", - "fs-extra": "^8.1.0", - "globby": "10.0.1", - "is-plain-object": "^3.0.0" - }, - "engines": { - "node": ">=8.3" - } - }, - "node_modules/rollup-plugin-copy/node_modules/@types/fs-extra": { - "version": "8.1.5", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.5.tgz", - "integrity": "sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/rollup-plugin-copy/node_modules/fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/rollup-plugin-copy/node_modules/globby": { - "version": "11.0.4", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.4.tgz", - "integrity": "sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/rollup-plugin-copy/node_modules/is-plain-object": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.1.tgz", - "integrity": "sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/rollup-plugin-copy/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/rollup-plugin-copy/node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/rollup-plugin-dts": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/rollup-plugin-dts/-/rollup-plugin-dts-6.1.1.tgz", - "integrity": "sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==", - "dev": true, - "license": "LGPL-3.0-only", - "dependencies": { - "magic-string": "^0.30.10" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/Swatinem" - }, - "optionalDependencies": { - "@babel/code-frame": "^7.24.2" - }, - "peerDependencies": { - "rollup": "^3.29.4 || ^4", - "typescript": "^4.5 || ^5.0" - } - }, - "node_modules/run-async": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/rxjs": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", - "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/safe-array-concat": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", - "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "get-intrinsic": "^1.2.4", - "has-symbols": "^1.0.3", - "isarray": "^2.0.5" - }, - "engines": { - "node": ">=0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safe-regex-test": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", - "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.6", - "es-errors": "^1.3.0", - "is-regex": "^1.1.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT" - }, - "node_modules/scheduler": { - "version": "0.23.2", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz", - "integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==", - "license": "MIT", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "license": "MIT" - }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.19.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true, - "license": "ISC" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/set-function-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", - "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "functions-have-names": "^1.2.3", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.1.tgz", - "integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/signal-exit": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", - "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "license": "ISC", - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/sigstore": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-2.3.1.tgz", - "integrity": "sha512-8G+/XDU8wNsJOQS5ysDVO0Etg9/2uA5gR9l4ZwijjlwxBcrU6RPfwi2+jJmbP+Ap1Hlp/nVAaEO4Fj22/SL2gQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@sigstore/bundle": "^2.3.2", - "@sigstore/core": "^1.0.0", - "@sigstore/protobuf-specs": "^0.3.2", - "@sigstore/sign": "^2.3.2", - "@sigstore/tuf": "^2.3.4", - "@sigstore/verify": "^1.2.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "license": "MIT" - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", - "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", - "dev": true, - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.4.tgz", - "integrity": "sha512-GNAq/eg8Udq2x0eNiFkr9gRg5bA7PXEWagQdeRX4cPSG+X/8V38v637gim9bjFptMk1QWsCTr0ttrJEiXbNnRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.1", - "debug": "^4.3.4", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-obj": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/spdx-correct": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", - "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-exceptions": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", - "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", - "dev": true, - "license": "CC-BY-3.0" - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.20", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.20.tgz", - "integrity": "sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/split": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", - "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", - "dev": true, - "license": "MIT", - "dependencies": { - "through": "2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/split2": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", - "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", - "dev": true, - "license": "ISC", - "dependencies": { - "readable-stream": "^3.0.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/ssri": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", - "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^7.0.3" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "license": "MIT", - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/string-width/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/string-width/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/string.prototype.trim": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", - "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.0", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", - "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", - "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strong-log-transformer": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", - "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "duplexer": "^0.1.1", - "minimist": "^1.2.0", - "through": "^2.3.4" - }, - "bin": { - "sl-log-transformer": "bin/sl-log-transformer.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/synckit": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", - "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@pkgr/core": "^0.1.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": "^14.18.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/unts" - } - }, - "node_modules/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dev": true, - "license": "ISC", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar/node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "dev": true, - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", - "integrity": "sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/template-node-express-zustand": { - "resolved": "create-live-compositor/templates/node-express-zustand", - "link": true - }, - "node_modules/template-node-minimal": { - "resolved": "create-live-compositor/templates/node-minimal", - "link": true - }, - "node_modules/text-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", - "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true, - "license": "MIT" - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/through2/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/through2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.14" - } - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", - "license": "MIT" - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "license": "MIT", - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/treeverse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/treeverse/-/treeverse-3.0.0.tgz", - "integrity": "sha512-gcANaAnd2QDZFmHFEOF4k7uc1J/6a6z3DJMd/QwEyxLoKGiptJRwid582r7QIsFlFMIZ3SnxfS52S4hm2DHkuQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==", - "dev": true, - "license": "0BSD" - }, - "node_modules/tuf-js": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz", - "integrity": "sha512-GwIJau9XaA8nLVbUXsN3IlFi7WmQ48gBUrl3FTkkL/XLu/POhBzfmX9hd33FNMX1qAsfl6ozO1iMmW9NC8YniA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@tufjs/models": "2.0.1", - "debug": "^4.3.4", - "make-fetch-happen": "^13.0.1" - }, - "engines": { - "node": "^16.14.0 || >=18.0.0" - } - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typed-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", - "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/typed-array-byte-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", - "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-byte-offset": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", - "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typed-array-length": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", - "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-proto": "^1.0.3", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/typescript": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz", - "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/typescript-eslint": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.8.1.tgz", - "integrity": "sha512-R0dsXFt6t4SAFjUSKFjMh4pXDtq04SsFKCVGDP3ZOzNP7itF0jBcZYU4fMsZr4y7O7V7Nc751dDeESbe4PbQMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/eslint-plugin": "8.8.1", - "@typescript-eslint/parser": "8.8.1", - "@typescript-eslint/utils": "8.8.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.8.1.tgz", - "integrity": "sha512-xfvdgA8AP/vxHgtgU310+WBnLB4uJQ9XdyP17RebG26rLtDrQJV3ZYrcopX91GrHmMoH8bdSwMRh2a//TiJ1jQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/type-utils": "8.8.1", - "@typescript-eslint/utils": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", - "graphemer": "^1.4.0", - "ignore": "^5.3.1", - "natural-compare": "^1.4.0", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0", - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/parser": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.8.1.tgz", - "integrity": "sha512-hQUVn2Lij2NAxVFEdvIGxT9gP1tq2yM83m+by3whWFsWC+1y8pxxxHUFE1UqDu2VsGi2i6RLcv4QvouM84U+ow==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/typescript-estree": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/scope-manager": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.8.1.tgz", - "integrity": "sha512-X4JdU+66Mazev/J0gfXlcC/dV6JI37h+93W9BRYXrSn0hrE64IoWgVkO9MSJgEzoWkxONgaQpICWg8vAN74wlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/type-utils": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.8.1.tgz", - "integrity": "sha512-qSVnpcbLP8CALORf0za+vjLYj1Wp8HSoiI8zYU5tHxRVj30702Z1Yw4cLwfNKhTPWp5+P+k1pjmD5Zd1nhxiZA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/typescript-estree": "8.8.1", - "@typescript-eslint/utils": "8.8.1", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/types": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.8.1.tgz", - "integrity": "sha512-WCcTP4SDXzMd23N27u66zTKMuEevH4uzU8C9jf0RO4E04yVHgQgW+r+TeVTNnO1KIfrL8ebgVVYYMMO3+jC55Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/typescript-estree": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.8.1.tgz", - "integrity": "sha512-A5d1R9p+X+1js4JogdNilDuuq+EHZdsH9MjTVxXOdVFfTJXunKJR/v+fNNyO4TnoOn5HqobzfRlc70NC6HTcdg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/visitor-keys": "8.8.1", - "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": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.8.1.tgz", - "integrity": "sha512-/QkNJDbV0bdL7H7d0/y0qBbV2HTtf0TIyjSDTvvmQEzeVx8jEImEbLuOA4EsvE8gIgqMitns0ifb5uQhMj8d9w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@typescript-eslint/scope-manager": "8.8.1", - "@typescript-eslint/types": "8.8.1", - "@typescript-eslint/typescript-estree": "8.8.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0" - } - }, - "node_modules/typescript-eslint/node_modules/@typescript-eslint/visitor-keys": { - "version": "8.8.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.8.1.tgz", - "integrity": "sha512-0/TdC3aeRAsW7MDvYRwEc1Uwm0TIBfzjPFgg60UU2Haj5qsCs9cc3zNgY71edqE3LbWfF/WoZQd3lJoDXFQpag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@typescript-eslint/types": "8.8.1", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/uglify-js": { - "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", - "dev": true, - "license": "BSD-2-Clause", - "optional": true, - "bin": { - "uglifyjs": "bin/uglifyjs" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/undici-types": { - "version": "6.19.8", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", - "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "license": "MIT" - }, - "node_modules/unique-filename": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-3.0.0.tgz", - "integrity": "sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==", - "dev": true, - "license": "ISC", - "dependencies": { - "unique-slug": "^4.0.0" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/unique-slug": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-4.0.0.tgz", - "integrity": "sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", - "integrity": "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/upath": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", - "integrity": "sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4", - "yarn": "*" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz", - "integrity": "sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.0" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", - "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", - "license": "MIT", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-10.0.0.tgz", - "integrity": "sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "license": "MIT" - }, - "node_modules/validate-npm-package-license": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/validate-npm-package-name": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", - "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", - "dev": true, - "license": "ISC", - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/vite": { - "version": "5.4.8", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.8.tgz", - "integrity": "sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "esbuild": "^0.21.3", - "postcss": "^8.4.43", - "rollup": "^4.20.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "sass-embedded": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-plugin-static-copy": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/vite-plugin-static-copy/-/vite-plugin-static-copy-1.0.6.tgz", - "integrity": "sha512-3uSvsMwDVFZRitqoWHj0t4137Kz7UynnJeq1EZlRW7e25h2068fyIZX4ORCCOAkfp1FklGxJNVJBkBOD+PZIew==", - "dev": true, - "license": "MIT", - "dependencies": { - "chokidar": "^3.5.3", - "fast-glob": "^3.2.11", - "fs-extra": "^11.1.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "peerDependencies": { - "vite": "^5.0.0" - } - }, - "node_modules/walk-up-path": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", - "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", - "dev": true, - "license": "ISC" - }, - "node_modules/wasm-pack": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/wasm-pack/-/wasm-pack-0.13.0.tgz", - "integrity": "sha512-AmboGZEnZoIcVCzSlkLEmNFEqJN+IwgshJ5S7pi30uNUTce4LvWkifQzsQRxnWj47G8gkqZxlyGlyQplsnIS7w==", - "dev": true, - "hasInstallScript": true, - "license": "MIT OR Apache-2.0", - "dependencies": { - "binary-install": "^1.0.1" - }, - "bin": { - "wasm-pack": "run.js" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", - "license": "BSD-2-Clause" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "license": "MIT", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/which-typed-array": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", - "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "has-tostringtag": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wide-align/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/wide-align/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/word-wrap": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", - "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/wrap-ansi-cjs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/wrap-ansi/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-file-atomic": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", - "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^4.0.1" - }, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } - }, - "node_modules/write-json-file": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-3.2.0.tgz", - "integrity": "sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "detect-indent": "^5.0.0", - "graceful-fs": "^4.1.15", - "make-dir": "^2.1.0", - "pify": "^4.0.1", - "sort-keys": "^2.0.0", - "write-file-atomic": "^2.4.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/write-json-file/node_modules/make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pify": "^4.0.1", - "semver": "^5.6.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/write-json-file/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/write-json-file/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/write-json-file/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/write-json-file/node_modules/write-file-atomic": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", - "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "graceful-fs": "^4.1.11", - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.2" - } - }, - "node_modules/write-pkg": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-4.0.0.tgz", - "integrity": "sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==", - "dev": true, - "license": "MIT", - "dependencies": { - "sort-keys": "^2.0.0", - "type-fest": "^0.4.1", - "write-json-file": "^3.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/write-pkg/node_modules/type-fest": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz", - "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==", - "dev": true, - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=6" - } - }, - "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true, - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true, - "license": "MIT" - }, - "node_modules/yargs/node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zustand": { - "version": "4.5.5", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.5.tgz", - "integrity": "sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==", - "license": "MIT", - "dependencies": { - "use-sync-external-store": "1.2.2" - }, - "engines": { - "node": ">=12.7.0" - }, - "peerDependencies": { - "@types/react": ">=16.8", - "immer": ">=9.0.6", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - } - } - } - } -} diff --git a/ts/package.json b/ts/package.json index 58950a5ea..f4aeb0e78 100644 --- a/ts/package.json +++ b/ts/package.json @@ -1,43 +1,35 @@ { - "name": "live-compositor-workspace", + "name": "live-compositor-root", "private": true, "version": "0.1.0", + "type": "module", "scripts": { - "lint": "lerna run lint", - "lint:fix": "lerna run lint -- --fix", - "build": "lerna run build --concurrency=1", - "build:sdk": "lerna run build --concurrency 1 --scope @live-compositor/core --scope @live-compositor/node --scope live-compositor", - "build:all": "npm run -w @live-compositor/browser-render build-wasm && npm run build", - "typecheck": "lerna run typecheck", - "clean": "lerna run clean", - "watch": "lerna run --parallel --stream watch --private", + "lint": "pnpm -r --no-bail run lint", + "lint:fix": "pnpm -r run lint -- --fix", + "build": "pnpm -r run build", + "build:sdk": "pnpm -C @live-compositor/core run build && pnpm -C @live-compositor/node run build && pnpm -C @live-compositor/web-wasm run build && pnpm -C live-compositor run build", + "build:all": "pnpm -C @live-compositor/browser-render run build-wasm && pnpm -r run build", + "typecheck": "pnpm -r run typecheck", + "clean": "pnpm -r run clean", + "watch": "pnpm -r --parallel --stream run watch", "generate-types": "node ./scripts/generateTypes.mjs" }, - "workspaces": [ - "live-compositor", - "@live-compositor/core", - "@live-compositor/node", - "@live-compositor/browser-render", - "examples/node-examples", - "examples/vite-browser-render", - "create-live-compositor", - "create-live-compositor/templates/node-minimal", - "create-live-compositor/templates/node-express-zustand" - ], "devDependencies": { "@eslint/plugin-kit": "^0.2.0", - "@typescript-eslint/eslint-plugin": "^7.16.0", - "@typescript-eslint/parser": "^7.18.0", + "@typescript-eslint/eslint-plugin": "^8.8.1", + "@typescript-eslint/parser": "^8.8.1", "concurrently": "^9.0.1", - "eslint": "^8.57.0", + "eslint": "^9.12.0", "eslint-config-prettier": "^9.1.0", "eslint-import-resolver-typescript": "^3.6.3", - "eslint-plugin-import": "^2.29.1", - "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-import": "^2.31.0", + "eslint-plugin-prettier": "^5.2.1", + "eslint-plugin-react-hooks": "^5.0.0", + "eslint-plugin-react-refresh": "^0.4.9", + "globals": "^15.9.0", "json-schema-to-typescript": "^15.0.1", - "lerna": "^8.1.8", - "prettier": "^3.3.2", - "typescript": "^5.5.3" + "prettier": "^3.3.3", + "typescript": "5.5.3" }, "overrides": { "rollup-plugin-copy": { diff --git a/ts/pnpm-lock.yaml b/ts/pnpm-lock.yaml new file mode 100644 index 000000000..1faa9833e --- /dev/null +++ b/ts/pnpm-lock.yaml @@ -0,0 +1,4916 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@eslint/plugin-kit': + specifier: ^0.2.0 + version: 0.2.3 + '@typescript-eslint/eslint-plugin': + specifier: ^8.8.1 + version: 8.14.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/parser': + specifier: ^8.8.1 + version: 8.14.0(eslint@9.15.0)(typescript@5.5.3) + concurrently: + specifier: ^9.0.1 + version: 9.1.0 + eslint: + specifier: ^9.12.0 + version: 9.15.0 + eslint-config-prettier: + specifier: ^9.1.0 + version: 9.1.0(eslint@9.15.0) + eslint-import-resolver-typescript: + specifier: ^3.6.3 + version: 3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0) + eslint-plugin-import: + specifier: ^2.31.0 + version: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + eslint-plugin-prettier: + specifier: ^5.2.1 + version: 5.2.1(eslint-config-prettier@9.1.0(eslint@9.15.0))(eslint@9.15.0)(prettier@3.3.3) + eslint-plugin-react-hooks: + specifier: ^5.0.0 + version: 5.0.0(eslint@9.15.0) + eslint-plugin-react-refresh: + specifier: ^0.4.9 + version: 0.4.14(eslint@9.15.0) + globals: + specifier: ^15.9.0 + version: 15.12.0 + json-schema-to-typescript: + specifier: ^15.0.1 + version: 15.0.3 + prettier: + specifier: ^3.3.3 + version: 3.3.3 + typescript: + specifier: 5.5.3 + version: 5.5.3 + + '@live-compositor/browser-render': + dependencies: + live-compositor: + specifier: workspace:0.1.0 + version: link:../../live-compositor + devDependencies: + '@rollup/plugin-typescript': + specifier: ^11.1.6 + version: 11.1.6(rollup@4.27.2)(tslib@2.8.1)(typescript@5.5.3) + rollup: + specifier: ^4.21.2 + version: 4.27.2 + rollup-plugin-copy: + specifier: ^3.5.0 + version: 3.5.0 + rollup-plugin-dts: + specifier: ^6.1.1 + version: 6.1.1(rollup@4.27.2)(typescript@5.5.3) + wasm-pack: + specifier: ^0.13.0 + version: 0.13.1 + + '@live-compositor/core': + dependencies: + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../live-compositor + react: + specifier: '*' + version: 18.3.1 + react-reconciler: + specifier: 0.29.2 + version: 0.29.2(react@18.3.1) + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + '@types/react-reconciler': + specifier: 0.28.8 + version: 0.28.8 + + '@live-compositor/node': + dependencies: + '@live-compositor/core': + specifier: workspace:^0.1.0 + version: link:../core + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + node-fetch: + specifier: ^2.6.7 + version: 2.7.0 + tar: + specifier: ^7.4.3 + version: 7.4.3 + uuid: + specifier: ^10.0.0 + version: 10.0.0 + ws: + specifier: ^8.18.0 + version: 8.18.0 + devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/node': + specifier: ^20.14.10 + version: 20.17.6 + '@types/node-fetch': + specifier: ^2.6.11 + version: 2.6.12 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + '@types/ws': + specifier: ^8.5.12 + version: 8.5.13 + + '@live-compositor/web-wasm': + dependencies: + '@datastructures-js/queue': + specifier: ^4.2.3 + version: 4.2.3 + '@live-compositor/browser-render': + specifier: workspace:0.1.0-rc.4 + version: link:../browser-render + '@live-compositor/core': + specifier: workspace:0.1.0 + version: link:../core + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../live-compositor + mp4box: + specifier: ^0.5.2 + version: 0.5.3 + path-parser: + specifier: ^6.1.0 + version: 6.1.0 + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + + create-live-compositor: + dependencies: + chalk: + specifier: ^4.1.2 + version: 4.1.2 + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/prompts': + specifier: ^2.4.9 + version: 2.4.9 + + create-live-compositor/templates/node-express-zustand: + dependencies: + '@live-compositor/node': + specifier: workspace:^0.1.0 + version: link:../../../@live-compositor/node + express: + specifier: ^4.21.0 + version: 4.21.1 + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../../live-compositor + react: + specifier: ^18.3.1 + version: 18.3.1 + zustand: + specifier: 4.5.5 + version: 4.5.5(@types/react@18.3.12)(react@18.3.1) + devDependencies: + '@types/express': + specifier: ^4.17.21 + version: 4.17.21 + '@types/node': + specifier: ^20.14.10 + version: 20.17.6 + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + + create-live-compositor/templates/node-minimal: + dependencies: + '@live-compositor/node': + specifier: workspace:^0.1.0 + version: link:../../../@live-compositor/node + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../../live-compositor + react: + specifier: ^18.3.1 + version: 18.3.1 + devDependencies: + '@types/node': + specifier: ^20.14.10 + version: 20.17.6 + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + typescript: + specifier: ^5.5.3 + version: 5.5.3 + + examples/node-examples: + dependencies: + '@live-compositor/node': + specifier: workspace:^0.1.0 + version: link:../../@live-compositor/node + fs-extra: + specifier: ^11.2.0 + version: 11.2.0 + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../live-compositor + node-fetch: + specifier: ^2.6.7 + version: 2.7.0 + react: + specifier: ^18.3.1 + version: 18.3.1 + ts-node: + specifier: ^10.9.2 + version: 10.9.2(@types/node@20.17.6)(typescript@5.5.3) + devDependencies: + '@types/fs-extra': + specifier: ^11.0.4 + version: 11.0.4 + '@types/node': + specifier: ^20.14.10 + version: 20.17.6 + '@types/node-fetch': + specifier: ^2.6.11 + version: 2.6.12 + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + + examples/vite-browser-render: + dependencies: + '@live-compositor/browser-render': + specifier: workspace:0.1.0-rc.4 + version: link:../../@live-compositor/browser-render + '@live-compositor/web-wasm': + specifier: workspace:0.1.0-rc.0 + version: link:../../@live-compositor/web-wasm + live-compositor: + specifier: workspace:^0.1.0 + version: link:../../live-compositor + mp4box: + specifier: ^0.5.2 + version: 0.5.3 + react: + specifier: ^18.3.1 + version: 18.3.1 + react-dom: + specifier: ^18.3.1 + version: 18.3.1(react@18.3.1) + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + '@types/react-dom': + specifier: ^18.3.0 + version: 18.3.1 + '@vitejs/plugin-react': + specifier: ^4.3.1 + version: 4.3.3(vite@5.4.11(@types/node@20.17.6)) + typescript: + specifier: ^5.5.3 + version: 5.5.3 + typescript-eslint: + specifier: ^8.0.1 + version: 8.14.0(eslint@9.15.0)(typescript@5.5.3) + vite: + specifier: ^5.4.1 + version: 5.4.11(@types/node@20.17.6) + vite-plugin-static-copy: + specifier: ^1.0.6 + version: 1.0.6(vite@5.4.11(@types/node@20.17.6)) + + live-compositor: + dependencies: + react: + specifier: '*' + version: 18.3.1 + devDependencies: + '@types/react': + specifier: ^18.3.3 + version: 18.3.12 + +packages: + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@apidevtools/json-schema-ref-parser@11.7.2': + resolution: {integrity: sha512-4gY54eEGEstClvEkGnwVkTkrx0sqwemEFG5OSRRn3tD91XH0+Q8XIkYIfo7IwEWPpJZwILb9GUXeShtplRc/eA==} + engines: {node: '>= 16'} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.26.2': + resolution: {integrity: sha512-Z0WgzSEa+aUcdiJuCIqgujCshpMWgUpgOxXotrYPSA53hA3qopNaqcJpyr0hVb1FeWdnqFA35/fUtXgBK8srQg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.2': + resolution: {integrity: sha512-zevQbhbau95nkoxSq3f/DC/SC+EEOUZd3DYqfSkMhY2/wfSeaHV1Ew4vk8e+x8lja31IbyuUa2uQ3JONqKbysw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.25.9': + resolution: {integrity: sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.26.2': + resolution: {integrity: sha512-DWMCZH9WA4Maitz2q21SRKHo9QXZxkDsbNZoVD62gusNtNBBqDg9i7uOhASfTfIGNzW+O+r7+jAlM8dwphcJKQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.0': + resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} + engines: {node: '>=6.9.0'} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@datastructures-js/queue@4.2.3': + resolution: {integrity: sha512-GWVMorC/xi2V2ta+Z/CPgPGHL2ZJozcj48g7y2nIX5GIGZGRrbShSHgvMViJwHJurUzJYOdIdRZnWDRrROFwJA==} + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.1': + resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.1': + resolution: {integrity: sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.19.0': + resolution: {integrity: sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.9.0': + resolution: {integrity: sha512-7ATR9F0e4W85D/0w7cU0SNj7qkAexMG+bAHEZOjo9akvGuhHE2m7umzWzfnpa0XAg5Kxc1BWmtPMV67jJ+9VUg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@3.2.0': + resolution: {integrity: sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@9.15.0': + resolution: {integrity: sha512-tMTqrY+EzbXmKJR5ToI8lxu7jaN5EdmrBFJpQk5JmSlyLsx6o4t27r883K5xsLuCYCpfKBCGswMSWXsM+jB7lg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.4': + resolution: {integrity: sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.2.3': + resolution: {integrity: sha512-2b/g5hRmpbb1o4GnTZax9N9m0FXzz9OV42ZzI4rDDMDuHUqigAiQCEWChBWCY4ztAGVRjoWT19v0yMmc5/L5kA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@humanfs/core@0.19.1': + resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.6': + resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/retry@0.3.1': + resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} + engines: {node: '>=18.18'} + + '@humanwhocodes/retry@0.4.1': + resolution: {integrity: sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==} + engines: {node: '>=18.18'} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@isaacs/fs-minipass@4.0.1': + resolution: {integrity: sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==} + engines: {node: '>=18.0.0'} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pkgr/core@0.1.1': + resolution: {integrity: sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + + '@rollup/plugin-typescript@11.1.6': + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/pluginutils@5.1.3': + resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/rollup-android-arm-eabi@4.27.2': + resolution: {integrity: sha512-Tj+j7Pyzd15wAdSJswvs5CJzJNV+qqSUcr/aCD+jpQSBtXvGnV0pnrjoc8zFTe9fcKCatkpFpOO7yAzpO998HA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.27.2': + resolution: {integrity: sha512-xsPeJgh2ThBpUqlLgRfiVYBEf/P1nWlWvReG+aBWfNv3XEBpa6ZCmxSVnxJgLgkNz4IbxpLy64h2gCmAAQLneQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.27.2': + resolution: {integrity: sha512-KnXU4m9MywuZFedL35Z3PuwiTSn/yqRIhrEA9j+7OSkji39NzVkgxuxTYg5F8ryGysq4iFADaU5osSizMXhU2A==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.27.2': + resolution: {integrity: sha512-Hj77A3yTvUeCIx/Vi+4d4IbYhyTwtHj07lVzUgpUq9YpJSEiGJj4vXMKwzJ3w5zp5v3PFvpJNgc/J31smZey6g==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.27.2': + resolution: {integrity: sha512-RjgKf5C3xbn8gxvCm5VgKZ4nn0pRAIe90J0/fdHUsgztd3+Zesb2lm2+r6uX4prV2eUByuxJNdt647/1KPRq5g==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.27.2': + resolution: {integrity: sha512-duq21FoXwQtuws+V9H6UZ+eCBc7fxSpMK1GQINKn3fAyd9DFYKPJNcUhdIKOrMFjLEJgQskoMoiuizMt+dl20g==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.27.2': + resolution: {integrity: sha512-6npqOKEPRZkLrMcvyC/32OzJ2srdPzCylJjiTJT2c0bwwSGm7nz2F9mNQ1WrAqCBZROcQn91Fno+khFhVijmFA==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.27.2': + resolution: {integrity: sha512-V9Xg6eXtgBtHq2jnuQwM/jr2mwe2EycnopO8cbOvpzFuySCGtKlPCI3Hj9xup/pJK5Q0388qfZZy2DqV2J8ftw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.27.2': + resolution: {integrity: sha512-uCFX9gtZJoQl2xDTpRdseYuNqyKkuMDtH6zSrBTA28yTfKyjN9hQ2B04N5ynR8ILCoSDOrG/Eg+J2TtJ1e/CSA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.27.2': + resolution: {integrity: sha512-/PU9P+7Rkz8JFYDHIi+xzHabOu9qEWR07L5nWLIUsvserrxegZExKCi2jhMZRd0ATdboKylu/K5yAXbp7fYFvA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.2': + resolution: {integrity: sha512-eCHmol/dT5odMYi/N0R0HC8V8QE40rEpkyje/ZAXJYNNoSfrObOvG/Mn+s1F/FJyB7co7UQZZf6FuWnN6a7f4g==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.27.2': + resolution: {integrity: sha512-DEP3Njr9/ADDln3kNi76PXonLMSSMiCir0VHXxmGSHxCxDfQ70oWjHcJGfiBugzaqmYdTC7Y+8Int6qbnxPBIQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.27.2': + resolution: {integrity: sha512-NHGo5i6IE/PtEPh5m0yw5OmPMpesFnzMIS/lzvN5vknnC1sXM5Z/id5VgcNPgpD+wHmIcuYYgW+Q53v+9s96lQ==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.27.2': + resolution: {integrity: sha512-PaW2DY5Tan+IFvNJGHDmUrORadbe/Ceh8tQxi8cmdQVCCYsLoQo2cuaSj+AU+YRX8M4ivS2vJ9UGaxfuNN7gmg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.27.2': + resolution: {integrity: sha512-dOlWEMg2gI91Qx5I/HYqOD6iqlJspxLcS4Zlg3vjk1srE67z5T2Uz91yg/qA8sY0XcwQrFzWWiZhMNERylLrpQ==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.27.2': + resolution: {integrity: sha512-euMIv/4x5Y2/ImlbGl88mwKNXDsvzbWUlT7DFky76z2keajCtcbAsN9LUdmk31hAoVmJJYSThgdA0EsPeTr1+w==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.27.2': + resolution: {integrity: sha512-RsnE6LQkUHlkC10RKngtHNLxb7scFykEbEwOFDjr3CeCMG+Rr+cKqlkKc2/wJ1u4u990urRHCbjz31x84PBrSQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.27.2': + resolution: {integrity: sha512-foJM5vv+z2KQmn7emYdDLyTbkoO5bkHZE1oth2tWbQNGW7mX32d46Hz6T0MqXdWS2vBZhaEtHqdy9WYwGfiliA==} + cpu: [x64] + os: [win32] + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/body-parser@1.19.5': + resolution: {integrity: sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/estree@1.0.6': + resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + + '@types/express-serve-static-core@4.19.6': + resolution: {integrity: sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==} + + '@types/express@4.17.21': + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} + + '@types/fs-extra@11.0.4': + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} + + '@types/fs-extra@8.1.5': + resolution: {integrity: sha512-0dzKcwO+S8s2kuF5Z9oUWatQJj5Uq/iqphEtE3GQJVRRYm/tD1LglU2UnXi2A8jLq5umkGouOXOR9y0n613ZwQ==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/http-errors@2.0.4': + resolution: {integrity: sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/jsonfile@6.1.4': + resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} + + '@types/lodash@4.17.13': + resolution: {integrity: sha512-lfx+dftrEZcdBPczf9d0Qv0x+j/rfNCMuC6OcfXmO8gkfeNAY88PgKUbvG56whcN23gc27yenwF6oJZXGFpYxg==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/node-fetch@2.6.12': + resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} + + '@types/node@20.17.6': + resolution: {integrity: sha512-VEI7OdvK2wP7XHnsuXbAJnEpEkF6NjSN45QJlL4VGqZSXsnicpesdTWsg9RISeSdYd3yeRj/y3k5KGjUXYnFwQ==} + + '@types/prompts@2.4.9': + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + + '@types/prop-types@15.7.13': + resolution: {integrity: sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==} + + '@types/qs@6.9.17': + resolution: {integrity: sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-dom@18.3.1': + resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==} + + '@types/react-reconciler@0.28.8': + resolution: {integrity: sha512-SN9c4kxXZonFhbX4hJrZy37yw9e7EIxcpHCxQv5JUS18wDE5ovkQKlqQEkufdJCCMfuI9BnjUJvhYeJ9x5Ra7g==} + + '@types/react@18.3.12': + resolution: {integrity: sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw==} + + '@types/send@0.17.4': + resolution: {integrity: sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==} + + '@types/serve-static@1.15.7': + resolution: {integrity: sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==} + + '@types/uuid@10.0.0': + resolution: {integrity: sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==} + + '@types/ws@8.5.13': + resolution: {integrity: sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA==} + + '@typescript-eslint/eslint-plugin@8.14.0': + resolution: {integrity: sha512-tqp8H7UWFaZj0yNO6bycd5YjMwxa6wIHOLZvWPkidwbgLCsBMetQoGj7DPuAlWa2yGO3H48xmPwjhsSPPCGU5w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.0.0 || ^8.0.0-alpha.0 + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.14.0': + resolution: {integrity: sha512-2p82Yn9juUJq0XynBXtFCyrBDb6/dJombnz6vbo6mgQEtWHfvHbQuEa9kAOVIt1c9YFwi7H6WxtPj1kg+80+RA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@8.14.0': + resolution: {integrity: sha512-aBbBrnW9ARIDn92Zbo7rguLnqQ/pOrUguVpbUwzOhkFg2npFDwTgPGqFqE0H5feXcOoJOfX3SxlJaKEVtq54dw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/type-utils@8.14.0': + resolution: {integrity: sha512-Xcz9qOtZuGusVOH5Uk07NGs39wrKkf3AxlkK79RBK6aJC1l03CobXjJbwBPSidetAOV+5rEVuiT1VSBUOAsanQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@8.14.0': + resolution: {integrity: sha512-yjeB9fnO/opvLJFAsPNYlKPnEM8+z4og09Pk504dkqonT02AyL5Z9SSqlE0XqezS93v6CXn49VHvB2G7XSsl0g==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@8.14.0': + resolution: {integrity: sha512-OPXPLYKGZi9XS/49rdaCbR5j/S14HazviBlUQFvSKz3npr3NikF+mrgK7CFVur6XEt95DZp/cmke9d5i3vtVnQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@8.14.0': + resolution: {integrity: sha512-OGqj6uB8THhrHj0Fk27DcHPojW7zKwKkPmHXHvQ58pLYp4hy8CSUdTKykKeh+5vFqTTVmjz0zCOOPKRovdsgHA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + + '@typescript-eslint/visitor-keys@8.14.0': + resolution: {integrity: sha512-vG0XZo8AdTH9OE6VFRwAZldNc7qtJ/6NLGWak+BtENuEUXGZgFpihILPiBvKXvJ2nFu27XNGC6rKiwuaoMbYzQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@vitejs/plugin-react@4.3.3': + resolution: {integrity: sha512-NooDe9GpHGqNns1i8XDERg0Vsg5SSYRhRxxyTGogUdkdNt47jal+fbuYi+Yfq6pzRCKXyoPcWisfxE6RIM3GKA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.14.0: + resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.1.0: + resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@6.2.1: + resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axios@0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + binary-install@1.1.0: + resolution: {integrity: sha512-rkwNGW+3aQVSZoD0/o3mfPN6Yxh3Id0R/xzTVBVVpGNlVz8EGwusksxRlbk/A5iKTZt9zkMn3qIqmAt3vpfbzg==} + engines: {node: '>=10'} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + caniuse-lite@1.0.30001680: + resolution: {integrity: sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chownr@3.0.0: + resolution: {integrity: sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==} + engines: {node: '>=18'} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concurrently@9.1.0: + resolution: {integrity: sha512-VxkzwMAn4LP7WyMnJNbHN5mKV9L2IbyDjpzemKr99sXNR3GqRNMMHdm7prV1ws9wg7ETj6WUkNOigZVsptwbgg==} + engines: {node: '>=18'} + hasBin: true + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.62: + resolution: {integrity: sha512-t8c+zLmJHa9dJy96yBZRXGQYoiCEnHYgFwn1asvSPZSUdVxnB62A4RASd7k41ytG3ErFBA0TpHlKg9D9SQBmLg==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.17.1: + resolution: {integrity: sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg==} + engines: {node: '>=10.13.0'} + + es-abstract@1.23.5: + resolution: {integrity: sha512-vlmniQ0WNPwXqA0BnmwV3Ng7HxiGlh6r5U6JcTMNx8OilcAGqVJBHJcPjqOMaczU9fRuRK5Px2BdVyPRnKMMVQ==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + eslint-config-prettier@9.1.0: + resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.6.3: + resolution: {integrity: sha512-ud9aw4szY9cCT1EWWdGv1L1XR6hh2PaRWif0j2QjQ0pgTY/69iw+W0Z4qZv5wHahOl8isEr+k/JnyAqNQkLkIA==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.31.0: + resolution: {integrity: sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-prettier@5.2.1: + resolution: {integrity: sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + '@types/eslint': '>=8.0.0' + eslint: '>=8.0.0' + eslint-config-prettier: '*' + prettier: '>=3.0.0' + peerDependenciesMeta: + '@types/eslint': + optional: true + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@5.0.0: + resolution: {integrity: sha512-hIOwI+5hYGpJEc4uPRmz2ulCjAGD/N13Lukkh8cLV0i2IRk/bdZDYjgLVHj+U9Z704kLIdIO6iueGvxNur0sgw==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react-refresh@0.4.14: + resolution: {integrity: sha512-aXvzCTK7ZBv1e7fahFuR3Z/fyQQSIQ711yPgYRj+Oj64tyTgO4iQIDmYXDBqvSWQ/FA4OSCsXOStlF+noU0/NA==} + peerDependencies: + eslint: '>=7' + + eslint-scope@8.2.0: + resolution: {integrity: sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.0: + resolution: {integrity: sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint@9.15.0: + resolution: {integrity: sha512-7CrWySmIibCgT1Os28lUU6upBshZ+GxybLOrmRzi08kS8MBuO8QA7pXEgYgY5W8vK3e74xv0lpjo9DbaGU9Rkw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.3.0: + resolution: {integrity: sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fdir@6.4.2: + resolution: {integrity: sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@3.3.0: + resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==} + engines: {node: '>=14'} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} + engines: {node: '>=14.14'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@10.4.5: + resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + hasBin: true + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Glob versions prior to v9 are no longer supported + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globals@15.12.0: + resolution: {integrity: sha512-1+gLErljJFhbOVyaetcwJiJ4+eLe45S2E7P5UiZ9xGfeq3ATQf5DOv9G7MH3gGbKQLkzmNh2DxfZwLdw+j6oTQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@10.0.1: + resolution: {integrity: sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==} + engines: {node: '>=8'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-bun-module@1.2.1: + resolution: {integrity: sha512-AmidtEM6D6NmUiLOvvU7+IePxjEjOzra2h0pSrsfSAcXwl/83zLLXDByafUJy9k/rKK0pvXMLdwKwGHlX2Ke6Q==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-object@3.0.1: + resolution: {integrity: sha512-Xnpx182SBMrr/aBik8y+GuR4U1L9FqMSojwDQwPMmxyC6bvEqly9UBCxhauBF5vNh2gwWJNX6oDV7O+OM4z34g==} + engines: {node: '>=0.10.0'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-schema-to-typescript@15.0.3: + resolution: {integrity: sha512-iOKdzTUWEVM4nlxpFudFsWyUiu/Jakkga4OZPEt7CGoSEsAsUgdOZqR6pcgx2STBek9Gm4hcarJpXSzIvZ/hKA==} + engines: {node: '>=16.0.0'} + hasBin: true + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + magic-string@0.30.12: + resolution: {integrity: sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw==} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@9.0.5: + resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.2: + resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + minizlib@3.0.1: + resolution: {integrity: sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==} + engines: {node: '>= 18'} + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mp4box@0.5.3: + resolution: {integrity: sha512-RIvyFZdPDIg3+mL6vUdPBSyQRrEfKO3ryAeJ4xJJV7HBHQUH3KfLlZRzfSpBHCd/HqR63HfbrWQI/CwXDvYENQ==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.3: + resolution: {integrity: sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-parser@6.1.0: + resolution: {integrity: sha512-nAB6J73z2rFcQP+870OHhpkHFj5kO4rPLc2Ol4Y3Ale7F6Hk1/cPKp7cQ8RznKF8FOSvu+YR9Xc6Gafk7DlpYA==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss@8.4.49: + resolution: {integrity: sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@3.3.3: + resolution: {integrity: sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==} + engines: {node: '>=14'} + hasBin: true + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-reconciler@0.29.2: + resolution: {integrity: sha512-zZQqIiYgDCTP/f1N/mAR10nJGrPD2ZR+jDSEsKWJHYC7Cm2wodlwbR3upZRdC3cjIjSlTLNVyO7Iu0Yy7t2AYg==} + engines: {node: '>=0.10.0'} + peerDependencies: + react: ^18.3.1 + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@5.0.10: + resolution: {integrity: sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==} + hasBin: true + + rollup-plugin-copy@3.5.0: + resolution: {integrity: sha512-wI8D5dvYovRMx/YYKtUNt3Yxaw4ORC9xo6Gt9t22kveWz1enG9QrhVlagzwrxSC455xD1dHMKhIJkbsQ7d48BA==} + engines: {node: '>=8.3'} + + rollup-plugin-dts@6.1.1: + resolution: {integrity: sha512-aSHRcJ6KG2IHIioYlvAOcEq6U99sVtqDDKVhnwt70rW6tsz3tv5OSjEiWcgzfsHdLyGXZ/3b/7b/+Za3Y6r1XA==} + engines: {node: '>=16'} + peerDependencies: + rollup: ^3.29.4 || ^4 + typescript: ^4.5 || ^5.0 + + rollup@4.27.2: + resolution: {integrity: sha512-KreA+PzWmk2yaFmZVwe6GB2uBD86nXl86OsDkt1bJS9p3vqWuEQ6HnJJ+j/mZi/q0920P99/MVRlB4L3crpF5w==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + search-params@3.0.0: + resolution: {integrity: sha512-8CYNl/bjkEhXWbDTU/K7c2jQtrnqEffIPyOLMqygW/7/b+ym8UtQumcAZjOfMLjZKR6AxK5tOr9fChbQZCzPqg==} + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.1: + resolution: {integrity: sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==} + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.1.0: + resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + engines: {node: '>=12'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + synckit@0.9.2: + resolution: {integrity: sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==} + engines: {node: ^14.18.0 || >=16.0.0} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + + tar@7.4.3: + resolution: {integrity: sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==} + engines: {node: '>=18'} + + tinyglobby@0.2.10: + resolution: {integrity: sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==} + engines: {node: '>=12.0.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tree-kill@1.2.2: + resolution: {integrity: sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==} + hasBin: true + + ts-api-utils@1.4.0: + resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} + engines: {node: '>=16'} + peerDependencies: + typescript: '>=4.2.0' + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typescript-eslint@8.14.0: + resolution: {integrity: sha512-K8fBJHxVL3kxMmwByvz8hNdBJ8a0YqKzKDX6jRlrjMuNXyd5T2V02HIq37+OiWXvUUOXgOOGiSSOh26Mh8pC3w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@10.0.0: + resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vite-plugin-static-copy@1.0.6: + resolution: {integrity: sha512-3uSvsMwDVFZRitqoWHj0t4137Kz7UynnJeq1EZlRW7e25h2068fyIZX4ORCCOAkfp1FklGxJNVJBkBOD+PZIew==} + engines: {node: ^18.0.0 || >=20.0.0} + peerDependencies: + vite: ^5.0.0 + + vite@5.4.11: + resolution: {integrity: sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + wasm-pack@0.13.1: + resolution: {integrity: sha512-P9exD4YkjpDbw68xUhF3MDm/CC/3eTmmthyG5bHJ56kalxOTewOunxTke4SyF8MTXV6jUtNjXggPgrGmMtczGg==} + hasBin: true + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yallist@5.0.0: + resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} + engines: {node: '>=18'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + zustand@4.5.5: + resolution: {integrity: sha512-+0PALYNJNgK6hldkgDq2vLrw5f6g/jCInz52n9RTpropGgeAf/ioFUCdtsjCqu4gNhW9D01rUQBROoRjdzyn2Q==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + +snapshots: + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@apidevtools/json-schema-ref-parser@11.7.2': + dependencies: + '@jsdevtools/ono': 7.1.3 + '@types/json-schema': 7.0.15 + js-yaml: 4.1.0 + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.26.2': {} + + '@babel/core@7.26.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + convert-source-map: 2.0.0 + debug: 4.3.7 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.26.2': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-compilation-targets@7.25.9': + dependencies: + '@babel/compat-data': 7.26.2 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.25.9': + dependencies: + '@babel/traverse': 7.25.9 + '@babel/types': 7.26.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.25.9': {} + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.26.0': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + + '@babel/parser@7.26.2': + dependencies: + '@babel/types': 7.26.0 + + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.25.9 + + '@babel/template@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + + '@babel/traverse@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.2 + '@babel/parser': 7.26.2 + '@babel/template': 7.25.9 + '@babel/types': 7.26.0 + debug: 4.3.7 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.26.0': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@datastructures-js/queue@4.2.3': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.1(eslint@9.15.0)': + dependencies: + eslint: 9.15.0 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.1': {} + + '@eslint/config-array@0.19.0': + dependencies: + '@eslint/object-schema': 2.1.4 + debug: 4.3.7 + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@eslint/core@0.9.0': {} + + '@eslint/eslintrc@3.2.0': + dependencies: + ajv: 6.12.6 + debug: 4.3.7 + espree: 10.3.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@9.15.0': {} + + '@eslint/object-schema@2.1.4': {} + + '@eslint/plugin-kit@0.2.3': + dependencies: + levn: 0.4.1 + + '@humanfs/core@0.19.1': {} + + '@humanfs/node@0.16.6': + dependencies: + '@humanfs/core': 0.19.1 + '@humanwhocodes/retry': 0.3.1 + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/retry@0.3.1': {} + + '@humanwhocodes/retry@0.4.1': {} + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.1.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@isaacs/fs-minipass@4.0.1': + dependencies: + minipass: 7.1.2 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jsdevtools/ono@7.1.3': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pkgr/core@0.1.1': {} + + '@rollup/plugin-typescript@11.1.6(rollup@4.27.2)(tslib@2.8.1)(typescript@5.5.3)': + dependencies: + '@rollup/pluginutils': 5.1.3(rollup@4.27.2) + resolve: 1.22.8 + typescript: 5.5.3 + optionalDependencies: + rollup: 4.27.2 + tslib: 2.8.1 + + '@rollup/pluginutils@5.1.3(rollup@4.27.2)': + dependencies: + '@types/estree': 1.0.6 + estree-walker: 2.0.2 + picomatch: 4.0.2 + optionalDependencies: + rollup: 4.27.2 + + '@rollup/rollup-android-arm-eabi@4.27.2': + optional: true + + '@rollup/rollup-android-arm64@4.27.2': + optional: true + + '@rollup/rollup-darwin-arm64@4.27.2': + optional: true + + '@rollup/rollup-darwin-x64@4.27.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.27.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.27.2': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.27.2': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.27.2': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.27.2': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.27.2': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.27.2': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.27.2': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.27.2': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.27.2': + optional: true + + '@rollup/rollup-linux-x64-musl@4.27.2': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.27.2': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.27.2': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.27.2': + optional: true + + '@rtsao/scc@1.1.0': {} + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.26.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.26.2 + '@babel/types': 7.26.0 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.26.0 + + '@types/body-parser@1.19.5': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 20.17.6 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 20.17.6 + + '@types/estree@1.0.6': {} + + '@types/express-serve-static-core@4.19.6': + dependencies: + '@types/node': 20.17.6 + '@types/qs': 6.9.17 + '@types/range-parser': 1.2.7 + '@types/send': 0.17.4 + + '@types/express@4.17.21': + dependencies: + '@types/body-parser': 1.19.5 + '@types/express-serve-static-core': 4.19.6 + '@types/qs': 6.9.17 + '@types/serve-static': 1.15.7 + + '@types/fs-extra@11.0.4': + dependencies: + '@types/jsonfile': 6.1.4 + '@types/node': 20.17.6 + + '@types/fs-extra@8.1.5': + dependencies: + '@types/node': 20.17.6 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 20.17.6 + + '@types/http-errors@2.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/jsonfile@6.1.4': + dependencies: + '@types/node': 20.17.6 + + '@types/lodash@4.17.13': {} + + '@types/mime@1.3.5': {} + + '@types/minimatch@5.1.2': {} + + '@types/node-fetch@2.6.12': + dependencies: + '@types/node': 20.17.6 + form-data: 4.0.1 + + '@types/node@20.17.6': + dependencies: + undici-types: 6.19.8 + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 20.17.6 + kleur: 3.0.3 + + '@types/prop-types@15.7.13': {} + + '@types/qs@6.9.17': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-dom@18.3.1': + dependencies: + '@types/react': 18.3.12 + + '@types/react-reconciler@0.28.8': + dependencies: + '@types/react': 18.3.12 + + '@types/react@18.3.12': + dependencies: + '@types/prop-types': 15.7.13 + csstype: 3.1.3 + + '@types/send@0.17.4': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 20.17.6 + + '@types/serve-static@1.15.7': + dependencies: + '@types/http-errors': 2.0.4 + '@types/node': 20.17.6 + '@types/send': 0.17.4 + + '@types/uuid@10.0.0': {} + + '@types/ws@8.5.13': + dependencies: + '@types/node': 20.17.6 + + '@typescript-eslint/eslint-plugin@8.14.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint@9.15.0)(typescript@5.5.3)': + dependencies: + '@eslint-community/regexpp': 4.12.1 + '@typescript-eslint/parser': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/type-utils': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/utils': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 8.14.0 + eslint: 9.15.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare: 1.4.0 + ts-api-utils: 1.4.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.5.3) + '@typescript-eslint/visitor-keys': 8.14.0 + debug: 4.3.7 + eslint: 9.15.0 + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@8.14.0': + dependencies: + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/visitor-keys': 8.14.0 + + '@typescript-eslint/type-utils@8.14.0(eslint@9.15.0)(typescript@5.5.3)': + dependencies: + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.5.3) + '@typescript-eslint/utils': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + debug: 4.3.7 + ts-api-utils: 1.4.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - eslint + - supports-color + + '@typescript-eslint/types@8.14.0': {} + + '@typescript-eslint/typescript-estree@8.14.0(typescript@5.5.3)': + dependencies: + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/visitor-keys': 8.14.0 + debug: 4.3.7 + fast-glob: 3.3.2 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.6.3 + ts-api-utils: 1.4.0(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@8.14.0(eslint@9.15.0)(typescript@5.5.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@typescript-eslint/scope-manager': 8.14.0 + '@typescript-eslint/types': 8.14.0 + '@typescript-eslint/typescript-estree': 8.14.0(typescript@5.5.3) + eslint: 9.15.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@8.14.0': + dependencies: + '@typescript-eslint/types': 8.14.0 + eslint-visitor-keys: 3.4.3 + + '@vitejs/plugin-react@4.3.3(vite@5.4.11(@types/node@20.17.6))': + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.4.11(@types/node@20.17.6) + transitivePeerDependencies: + - supports-color + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@8.14.0): + dependencies: + acorn: 8.14.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.14.0 + + acorn@8.14.0: {} + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ansi-regex@5.0.1: {} + + ansi-regex@6.1.0: {} + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@6.2.1: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + arg@4.1.3: {} + + argparse@2.0.1: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-flatten@1.1.1: {} + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + asynckit@0.4.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + axios@0.26.1: + dependencies: + follow-redirects: 1.15.9 + transitivePeerDependencies: + - debug + + balanced-match@1.0.2: {} + + binary-extensions@2.3.0: {} + + binary-install@1.1.0: + dependencies: + axios: 0.26.1 + rimraf: 3.0.2 + tar: 6.2.1 + transitivePeerDependencies: + - debug + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.24.2: + dependencies: + caniuse-lite: 1.0.30001680 + electron-to-chromium: 1.5.62 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) + + bytes@3.1.2: {} + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + caniuse-lite@1.0.30001680: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chownr@2.0.0: {} + + chownr@3.0.0: {} + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.4: {} + + colorette@1.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + concat-map@0.0.1: {} + + concurrently@9.1.0: + dependencies: + chalk: 4.1.2 + lodash: 4.17.21 + rxjs: 7.8.1 + shell-quote: 1.8.1 + supports-color: 8.1.1 + tree-kill: 1.2.2 + yargs: 17.7.2 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.7.1: {} + + create-require@1.1.1: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + csstype@3.1.3: {} + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.7: + dependencies: + ms: 2.1.3 + + deep-is@0.1.4: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + diff@4.0.2: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.62: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.17.1: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + es-abstract@1.23.5: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.3 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@4.0.0: {} + + eslint-config-prettier@9.1.0(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.3.7 + enhanced-resolve: 5.17.1 + eslint: 9.15.0 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0))(eslint@9.15.0) + fast-glob: 3.3.2 + get-tsconfig: 4.8.1 + is-bun-module: 1.2.1 + is-glob: 4.0.3 + optionalDependencies: + eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0) + transitivePeerDependencies: + - '@typescript-eslint/parser' + - eslint-import-resolver-node + - eslint-import-resolver-webpack + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0))(eslint@9.15.0): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + eslint: 9.15.0 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0) + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-typescript@3.6.3)(eslint@9.15.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.15.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.6.3(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint-plugin-import@2.31.0)(eslint@9.15.0))(eslint@9.15.0) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + string.prototype.trimend: 1.0.8 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-prettier@5.2.1(eslint-config-prettier@9.1.0(eslint@9.15.0))(eslint@9.15.0)(prettier@3.3.3): + dependencies: + eslint: 9.15.0 + prettier: 3.3.3 + prettier-linter-helpers: 1.0.0 + synckit: 0.9.2 + optionalDependencies: + eslint-config-prettier: 9.1.0(eslint@9.15.0) + + eslint-plugin-react-hooks@5.0.0(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + + eslint-plugin-react-refresh@0.4.14(eslint@9.15.0): + dependencies: + eslint: 9.15.0 + + eslint-scope@8.2.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.0: {} + + eslint@9.15.0: + dependencies: + '@eslint-community/eslint-utils': 4.4.1(eslint@9.15.0) + '@eslint-community/regexpp': 4.12.1 + '@eslint/config-array': 0.19.0 + '@eslint/core': 0.9.0 + '@eslint/eslintrc': 3.2.0 + '@eslint/js': 9.15.0 + '@eslint/plugin-kit': 0.2.3 + '@humanfs/node': 0.16.6 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.1 + '@types/estree': 1.0.6 + '@types/json-schema': 7.0.15 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.3.7 + escape-string-regexp: 4.0.0 + eslint-scope: 8.2.0 + eslint-visitor-keys: 4.2.0 + espree: 10.3.0 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + 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.4 + transitivePeerDependencies: + - supports-color + + espree@10.3.0: + dependencies: + acorn: 8.14.0 + acorn-jsx: 5.3.2(acorn@8.14.0) + eslint-visitor-keys: 4.2.0 + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@5.3.0: {} + + estree-walker@2.0.2: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fdir@6.4.2(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@4.0.1: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + + flatted@3.3.1: {} + + follow-redirects@1.15.9: {} + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@3.3.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fs-extra@11.2.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@10.4.5: + dependencies: + foreground-child: 3.3.0 + jackspeak: 3.4.3 + minimatch: 9.0.5 + minipass: 7.1.2 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + globals@11.12.0: {} + + globals@14.0.0: {} + + globals@15.12.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@10.0.1: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + glob: 7.2.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + has-bigints@1.0.2: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + imurmurhash@0.1.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + ipaddr.js@1.9.1: {} + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-bun-module@1.2.1: + dependencies: + semver: 7.6.3 + + is-callable@1.2.7: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@3.0.0: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-plain-object@3.0.1: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + js-tokens@4.0.0: {} + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsesc@3.0.2: {} + + json-buffer@3.0.1: {} + + json-schema-to-typescript@15.0.3: + dependencies: + '@apidevtools/json-schema-ref-parser': 11.7.2 + '@types/json-schema': 7.0.15 + '@types/lodash': 4.17.13 + is-glob: 4.0.3 + js-yaml: 4.1.0 + lodash: 4.17.21 + minimist: 1.2.8 + prettier: 3.3.3 + tinyglobby: 0.2.10 + + json-schema-traverse@0.4.1: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + kleur@3.0.3: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash.merge@4.6.2: {} + + lodash@4.17.21: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lru-cache@10.4.3: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + magic-string@0.30.12: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.0 + + make-error@1.3.6: {} + + media-typer@0.3.0: {} + + merge-descriptors@1.0.3: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@9.0.5: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@5.0.0: {} + + minipass@7.1.2: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + minizlib@3.0.1: + dependencies: + minipass: 7.1.2 + rimraf: 5.0.10 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mp4box@0.5.3: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + nanoid@3.3.7: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-releases@2.0.18: {} + + normalize-path@3.0.0: {} + + object-inspect@1.13.3: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + package-json-from-dist@1.0.1: {} + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-parser@6.1.0: + dependencies: + search-params: 3.0.0 + tslib: 1.14.1 + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.2 + + path-to-regexp@0.1.10: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + possible-typed-array-names@1.0.0: {} + + postcss@8.4.49: + dependencies: + nanoid: 3.3.7 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@3.3.3: {} + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + punycode@2.3.1: {} + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + queue-microtask@1.2.3: {} + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-reconciler@0.29.2(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-refresh@0.14.2: {} + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + require-directory@2.1.1: {} + + resolve-from@4.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + reusify@1.0.4: {} + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@5.0.10: + dependencies: + glob: 10.4.5 + + rollup-plugin-copy@3.5.0: + dependencies: + '@types/fs-extra': 8.1.5 + colorette: 1.4.0 + fs-extra: 8.1.0 + globby: 10.0.1 + is-plain-object: 3.0.1 + + rollup-plugin-dts@6.1.1(rollup@4.27.2)(typescript@5.5.3): + dependencies: + magic-string: 0.30.12 + rollup: 4.27.2 + typescript: 5.5.3 + optionalDependencies: + '@babel/code-frame': 7.26.2 + + rollup@4.27.2: + dependencies: + '@types/estree': 1.0.6 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.27.2 + '@rollup/rollup-android-arm64': 4.27.2 + '@rollup/rollup-darwin-arm64': 4.27.2 + '@rollup/rollup-darwin-x64': 4.27.2 + '@rollup/rollup-freebsd-arm64': 4.27.2 + '@rollup/rollup-freebsd-x64': 4.27.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.27.2 + '@rollup/rollup-linux-arm-musleabihf': 4.27.2 + '@rollup/rollup-linux-arm64-gnu': 4.27.2 + '@rollup/rollup-linux-arm64-musl': 4.27.2 + '@rollup/rollup-linux-powerpc64le-gnu': 4.27.2 + '@rollup/rollup-linux-riscv64-gnu': 4.27.2 + '@rollup/rollup-linux-s390x-gnu': 4.27.2 + '@rollup/rollup-linux-x64-gnu': 4.27.2 + '@rollup/rollup-linux-x64-musl': 4.27.2 + '@rollup/rollup-win32-arm64-msvc': 4.27.2 + '@rollup/rollup-win32-ia32-msvc': 4.27.2 + '@rollup/rollup-win32-x64-msvc': 4.27.2 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rxjs@7.8.1: + dependencies: + tslib: 2.8.1 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safer-buffer@2.1.2: {} + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + search-params@3.0.0: {} + + semver@6.3.1: {} + + semver@7.6.3: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + setprototypeof@1.2.0: {} + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.1: {} + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.3 + + signal-exit@4.1.0: {} + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + source-map-js@1.2.1: {} + + statuses@2.0.1: {} + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.1.0 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.5 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.1.0: + dependencies: + ansi-regex: 6.1.0 + + strip-bom@3.0.0: {} + + strip-json-comments@3.1.1: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + synckit@0.9.2: + dependencies: + '@pkgr/core': 0.1.1 + tslib: 2.8.1 + + tapable@2.2.1: {} + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tar@7.4.3: + dependencies: + '@isaacs/fs-minipass': 4.0.1 + chownr: 3.0.0 + minipass: 7.1.2 + minizlib: 3.0.1 + mkdirp: 3.0.1 + yallist: 5.0.0 + + tinyglobby@0.2.10: + dependencies: + fdir: 6.4.2(picomatch@4.0.2) + picomatch: 4.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tr46@0.0.3: {} + + tree-kill@1.2.2: {} + + ts-api-utils@1.4.0(typescript@5.5.3): + dependencies: + typescript: 5.5.3 + + ts-node@10.9.2(@types/node@20.17.6)(typescript@5.5.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 20.17.6 + acorn: 8.14.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.5.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typescript-eslint@8.14.0(eslint@9.15.0)(typescript@5.5.3): + dependencies: + '@typescript-eslint/eslint-plugin': 8.14.0(@typescript-eslint/parser@8.14.0(eslint@9.15.0)(typescript@5.5.3))(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/parser': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + '@typescript-eslint/utils': 8.14.0(eslint@9.15.0)(typescript@5.5.3) + optionalDependencies: + typescript: 5.5.3 + transitivePeerDependencies: + - eslint + - supports-color + + typescript@5.5.3: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + undici-types@6.19.8: {} + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.1.1(browserslist@4.24.2): + dependencies: + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + use-sync-external-store@1.2.2(react@18.3.1): + dependencies: + react: 18.3.1 + + utils-merge@1.0.1: {} + + uuid@10.0.0: {} + + v8-compile-cache-lib@3.0.1: {} + + vary@1.1.2: {} + + vite-plugin-static-copy@1.0.6(vite@5.4.11(@types/node@20.17.6)): + dependencies: + chokidar: 3.6.0 + fast-glob: 3.3.2 + fs-extra: 11.2.0 + picocolors: 1.1.1 + vite: 5.4.11(@types/node@20.17.6) + + vite@5.4.11(@types/node@20.17.6): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.49 + rollup: 4.27.2 + optionalDependencies: + '@types/node': 20.17.6 + fsevents: 2.3.3 + + wasm-pack@0.13.1: + dependencies: + binary-install: 1.1.0 + transitivePeerDependencies: + - debug + + webidl-conversions@3.0.1: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + word-wrap@1.2.5: {} + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.1 + string-width: 5.1.2 + strip-ansi: 7.1.0 + + wrappy@1.0.2: {} + + ws@8.18.0: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yallist@5.0.0: {} + + yargs-parser@21.1.1: {} + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + zustand@4.5.5(@types/react@18.3.12)(react@18.3.1): + dependencies: + use-sync-external-store: 1.2.2(react@18.3.1) + optionalDependencies: + '@types/react': 18.3.12 + react: 18.3.1 diff --git a/ts/pnpm-workspace.yaml b/ts/pnpm-workspace.yaml new file mode 100644 index 000000000..8a5766dd2 --- /dev/null +++ b/ts/pnpm-workspace.yaml @@ -0,0 +1,11 @@ +packages: + - 'live-compositor' + - '@live-compositor/core' + - '@live-compositor/node' + - '@live-compositor/browser-render' + - '@live-compositor/web-wasm' + - 'examples/node-examples' + - 'examples/vite-browser-render' + - 'create-live-compositor' + - 'create-live-compositor/templates/node-minimal' + - 'create-live-compositor/templates/node-express-zustand' diff --git a/ts/tsconfig.base.json b/ts/tsconfig.json similarity index 100% rename from ts/tsconfig.base.json rename to ts/tsconfig.json diff --git a/vk-video/Cargo.toml b/vk-video/Cargo.toml index becd44adf..deedb94ef 100644 --- a/vk-video/Cargo.toml +++ b/vk-video/Cargo.toml @@ -6,20 +6,28 @@ authors = ["Software Mansion "] readme = "README.md" license = "MIT" repository = "https://github.com/software-mansion/live-compositor" +rust-version = "1.81" +description = "A library for hardware video coding using Vulkan Video, with wgpu integration." +categories = ["multimedia::video", "multimedia::encoding", "hardware-support", "encoding", "graphics"] +keywords = ["vulkan", "video", "wgpu", "decoding", "h264"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] ash = "0.38.0" +bytes = "1" derivative = "2.2.0" -h264-reader = { git = "https://github.com/membraneframework-labs/h264-reader.git", branch = "@jerzywilczek/scaling-lists" } +h264-reader = { git = "https://github.com/membraneframework-labs/h264-reader.git", branch = "live-compositor" } thiserror = "1.0.59" tracing = "0.1.40" vk-mem = "0.4.0" wgpu = "22.1.0" [dev-dependencies] +bytemuck = { version = "1.19.0", features = ["derive"] } +clap = { version = "4.5.20", features = ["derive"] } tracing-subscriber = "0.3.18" +winit = "0.29" [build-dependencies] cfg_aliases = "0.2.1" diff --git a/vk-video/README.md b/vk-video/README.md new file mode 100644 index 000000000..c0f848952 --- /dev/null +++ b/vk-video/README.md @@ -0,0 +1,91 @@ +# vk-video + +A library for hardware video coding using Vulkan Video, with [wgpu] integration. + +[![Crates.io][crates-badge]][crates-url] +[![docs.rs][docs-badge]][docs-url] +[![MIT licensed][mit-badge]][mit-url] +[![Build Status][actions-badge]][actions-url] + +[crates-badge]: https://img.shields.io/crates/v/vk-video +[crates-url]: https://crates.io/crates/vk-video +[mit-badge]: https://img.shields.io/badge/license-MIT-blue.svg +[mit-url]: https://github.com/software-mansion/live-compositor/blob/master/vk-video/LICENSE +[actions-badge]: https://github.com/software-mansion/live-compositor/actions/workflows/test.yml/badge.svg +[actions-url]: https://github.com/software-mansion/live-compositor/actions/workflows/test.yml?query=branch%3Amaster +[docs-badge]: https://img.shields.io/docsrs/vk-video +[docs-url]: https://docs.rs/vk-video/latest/vk-video/ + +## Overview + +The goal of this library is to provide easy access to hardware video coding. You can use it to decode a video frame into a `Vec` with pixel data, or into a [`wgpu::Texture`]. Currently, we only support H.264 (aka AVC or MPEG 4 Part 10) decoding, but we plan to support at least H.264 encoding and hopefully other codecs supported by Vulkan Video. + +An advantage of using this library with wgpu is that decoded video frames never leave the GPU memory. There's no copying the frames to RAM and back to the GPU, so it should be quite fast if you want to use them for rendering. + +## Usage + +```rs +fn decode_video( + window: &winit::window::Window, + mut encoded_video_reader: impl std::io::Read, +) { + let instance = vk_video::VulkanInstance::new().unwrap(); + let mut surface = instance.wgpu_instance.create_surface(window).unwrap(); + let device = instance + .create_device( + wgpu::Features::empty(), + wgpu::Limits::default(), + &mut Some(&mut surface), + ) + .unwrap(); + + let mut decoder = device.create_wgpu_textures_decoder().unwrap(); + let mut buffer = vec![0; 4096]; + + while let Ok(n) = encoded_video_reader.read(&mut buffer) { + if n == 0 { + return; + } + + let decoded_frames = decoder.decode(&buffer[..n], None).unwrap(); + + for frame in decoded_frames { + // Each frame contains a wgpu::Texture you can sample for drawing. + // device.wgpu_device is a wgpu::Device and device.wgpu_queue + // is a wgpu::Queue. You can use these for interacting with the frames. + } + } +} +``` +Be sure to check out our examples, especially the `player` example, which is a simple video player built using this library and wgpu. Because the player is very simple, you need to extract the raw h264 data from a container before usage. Here's an example on how to extract the h264 bytestream out of an mp4 file using ffmpeg: + +```sh +ffmpeg -i input.mp4 -c:v copy -bsf:v h264_mp4toannexb -an output.h264 +``` + +Then you can run the example with: + +```sh +git clone https://github.com/software-mansion/live-compositor.git +cd live-compositor/vk-video +cargo run --example player -- output.h264 FRAMERATE +``` + +## Compatibility + +On Linux, the library should work on NVIDIA GPUs out of the box. For AMD GPUs with recent Mesa drivers, you need to set the `RADV_PERFTEST=video_decode` environment variable for now: + +```sh +RADV_PERFTEST=video_decode cargo run +``` + +It should work on Windows with recent drivers out of the box. Be sure to submit an issue if it doesn't. + +[wgpu]: https://wgpu.rs/ +[`wgpu::Texture`]: https://docs.rs/wgpu/latest/wgpu/struct.Texture.html + +## vk-video is created by Software Mansion + +[![swm](https://logo.swmansion.com/logo?color=white&variant=desktop&width=150&tag=live-compositor-vk-video 'Software Mansion')](https://swmansion.com) + +Since 2012 [Software Mansion](https://swmansion.com) is a software agency with experience in building web and mobile apps as well as complex multimedia solutions. We are Core React Native Contributors and experts in live streaming and broadcasting technologies. We can help you build your next dream product – [Hire us](https://swmansion.com/contact/projects?utm_source=live-compositor-vk-video&utm_medium=readme). diff --git a/vk-video/build.rs b/vk-video/build.rs index 6fc1495c2..928e40213 100644 --- a/vk-video/build.rs +++ b/vk-video/build.rs @@ -1,13 +1,13 @@ fn main() { cfg_aliases::cfg_aliases! { - vulkan: { - any( - windows, - all( - unix, - not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")) - ) + vulkan: { + any( + windows, + all( + unix, + not(any(target_os = "macos", target_os = "ios", target_os = "emscripten")) ) + ) }, } } diff --git a/vk-video/examples/basic.rs b/vk-video/examples/basic.rs index 388078fb3..a39fc93d5 100644 --- a/vk-video/examples/basic.rs +++ b/vk-video/examples/basic.rs @@ -2,6 +2,8 @@ fn main() { use std::io::Write; + use vk_video::{Frame, VulkanInstance}; + let subscriber = tracing_subscriber::FmtSubscriber::builder() .with_max_level(tracing::Level::INFO) .finish(); @@ -16,24 +18,26 @@ fn main() { let h264_bytestream = std::fs::read(&args[1]).unwrap_or_else(|_| panic!("read {}", args[1])); - let vulkan_ctx = std::sync::Arc::new( - vk_video::VulkanCtx::new( + let vulkan_instance = VulkanInstance::new().unwrap(); + let vulkan_device = vulkan_instance + .create_device( wgpu::Features::empty(), wgpu::Limits { max_push_constant_size: 128, ..Default::default() }, + &mut None, ) - .unwrap(), - ); - let mut decoder = vk_video::Decoder::new(vulkan_ctx).unwrap(); + .unwrap(); + + let mut decoder = vulkan_device.create_bytes_decoder().unwrap(); let mut output_file = std::fs::File::create("output.nv12").unwrap(); for chunk in h264_bytestream.chunks(256) { - let frames = decoder.decode_to_bytes(chunk).unwrap(); + let frames = decoder.decode(chunk, None).unwrap(); - for frame in frames { + for Frame { frame, .. } in frames { output_file.write_all(&frame).unwrap(); } } diff --git a/vk-video/examples/player/main.rs b/vk-video/examples/player/main.rs new file mode 100644 index 000000000..c10caef60 --- /dev/null +++ b/vk-video/examples/player/main.rs @@ -0,0 +1,14 @@ +#[cfg(vulkan)] +mod player; + +#[cfg(vulkan)] +fn main() { + player::run() +} + +#[cfg(not(vulkan))] +fn main() { + println!( + "This crate doesn't work on your operating system, because it does not support vulkan" + ); +} diff --git a/vk-video/examples/player/player.rs b/vk-video/examples/player/player.rs new file mode 100644 index 000000000..4fd14ddda --- /dev/null +++ b/vk-video/examples/player/player.rs @@ -0,0 +1,64 @@ +use std::{path::PathBuf, sync::mpsc, time::Duration}; + +use clap::Parser; +use vk_video::VulkanInstance; +use winit::{event_loop::EventLoop, window::WindowBuilder}; + +mod decoder; +mod renderer; + +const FRAMES_BUFFER_LEN: usize = 3; + +#[derive(Parser)] +#[command(version, about, long_about=None)] +struct Args { + /// an .h264 file to play + filename: PathBuf, + + /// framerate to play the video at + framerate: u64, +} + +struct FrameWithPts { + frame: wgpu::Texture, + /// Presentation timestamp + pts: Duration, +} + +pub fn run() { + let args = Args::parse(); + let subscriber = tracing_subscriber::fmt() + .with_max_level(tracing::Level::INFO) + .finish(); + + tracing::subscriber::set_global_default(subscriber).unwrap(); + + let file = std::fs::File::open(&args.filename).expect("open file"); + + let event_loop = EventLoop::new().unwrap(); + let window = WindowBuilder::new().build(&event_loop).unwrap(); + + let vulkan_instance = VulkanInstance::new().unwrap(); + + let mut surface = vulkan_instance + .wgpu_instance + .create_surface(&window) + .unwrap(); + + let vulkan_device = vulkan_instance + .create_device( + wgpu::Features::empty(), + wgpu::Limits::default(), + &mut Some(&mut surface), + ) + .unwrap(); + + let (tx, rx) = mpsc::sync_channel(FRAMES_BUFFER_LEN); + let vulkan_device_clone = vulkan_device.clone(); + + std::thread::spawn(move || { + decoder::run_decoder(tx, args.framerate, vulkan_device_clone, file); + }); + + renderer::run_renderer(event_loop, &window, surface, &vulkan_device, rx); +} diff --git a/vk-video/examples/player/player/decoder.rs b/vk-video/examples/player/player/decoder.rs new file mode 100644 index 000000000..09ab0018e --- /dev/null +++ b/vk-video/examples/player/player/decoder.rs @@ -0,0 +1,43 @@ +use std::{ + io::Read, + sync::{mpsc::SyncSender, Arc}, + time::Duration, +}; + +use bytes::BytesMut; +use vk_video::VulkanDevice; + +use super::FrameWithPts; + +pub fn run_decoder( + tx: SyncSender, + framerate: u64, + vulkan_device: Arc, + mut bytestream_reader: impl Read, +) { + let mut decoder = vulkan_device.create_wgpu_textures_decoder().unwrap(); + let frame_interval = 1.0 / (framerate as f64); + let mut frame_number = 0u64; + let mut buffer = BytesMut::zeroed(4096); + + while let Ok(n) = bytestream_reader.read(&mut buffer) { + if n == 0 { + return; + } + + let decoded = decoder.decode(&buffer[..n], None).unwrap(); + + for f in decoded { + let result = FrameWithPts { + frame: f.frame, + pts: Duration::from_secs_f64(frame_number as f64 * frame_interval), + }; + + frame_number += 1; + + if tx.send(result).is_err() { + return; + } + } + } +} diff --git a/vk-video/examples/player/player/renderer.rs b/vk-video/examples/player/player/renderer.rs new file mode 100644 index 000000000..fafb7664c --- /dev/null +++ b/vk-video/examples/player/player/renderer.rs @@ -0,0 +1,353 @@ +use std::sync::{mpsc::Receiver, Arc}; + +use vk_video::VulkanDevice; +use wgpu::util::DeviceExt; +use winit::{ + dpi::PhysicalSize, + event::{ElementState, Event, KeyEvent, WindowEvent}, + event_loop::EventLoop, + keyboard::{KeyCode, PhysicalKey}, + window::Window, +}; + +use super::FrameWithPts; + +pub fn run_renderer<'a>( + event_loop: EventLoop<()>, + window: &'a Window, + surface: wgpu::Surface<'a>, + vulkan_device: &VulkanDevice, + rx: Receiver, +) { + let mut current_frame = rx.recv().unwrap(); + let mut next_frame = None; + + window.set_title("vk-video example player"); + window.set_resizable(false); + let _ = window.request_inner_size(PhysicalSize::new( + current_frame.frame.size().width, + current_frame.frame.size().height, + )); + + let mut renderer = Renderer::new(surface, vulkan_device, window); + + let start_timestamp = std::time::Instant::now(); + event_loop + .run(move |event, cf| match event { + Event::WindowEvent { window_id, event } if window_id == window.id() => match event { + WindowEvent::KeyboardInput { + event: + KeyEvent { + state: ElementState::Pressed, + physical_key: PhysicalKey::Code(KeyCode::Escape), + .. + }, + .. + } + | WindowEvent::CloseRequested => cf.exit(), + + WindowEvent::RedrawRequested => { + window.request_redraw(); + if next_frame.is_none() { + if let Ok(f) = rx.try_recv() { + next_frame = Some(f); + } + } + + let current_pts = std::time::Instant::now() - start_timestamp; + if let Some(next_frame_pts) = next_frame.as_ref().map(|f| f.pts) { + if next_frame_pts < current_pts { + current_frame = next_frame.take().unwrap(); + } + } + + let _ = window.request_inner_size(PhysicalSize::new( + current_frame.frame.size().width, + current_frame.frame.size().height, + )); + + renderer.render(¤t_frame.frame, window).unwrap(); + } + + WindowEvent::Resized(new_size) => renderer.resize(new_size), + _ => {} + }, + _ => {} + }) + .unwrap(); +} + +#[derive(Debug, Clone, Copy, bytemuck::Zeroable, bytemuck::Pod)] +#[repr(C)] +struct Vertex { + position: [f32; 3], + texture_coords: [f32; 2], +} + +impl Vertex { + const ATTRIBUTES: &[wgpu::VertexAttribute] = + &wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x2]; + const LAYOUT: wgpu::VertexBufferLayout<'static> = wgpu::VertexBufferLayout { + step_mode: wgpu::VertexStepMode::Vertex, + attributes: Self::ATTRIBUTES, + array_stride: std::mem::size_of::() as wgpu::BufferAddress, + }; +} + +const VERTICES: &[Vertex] = &[ + Vertex { + position: [-1.0, 1.0, 0.0], + texture_coords: [0.0, 0.0], + }, + Vertex { + position: [-1.0, -1.0, 0.0], + texture_coords: [0.0, 1.0], + }, + Vertex { + position: [1.0, -1.0, 0.0], + texture_coords: [1.0, 1.0], + }, + Vertex { + position: [1.0, 1.0, 0.0], + texture_coords: [1.0, 0.0], + }, +]; + +const INDICES: &[u16] = &[0, 1, 3, 1, 2, 3]; + +struct Renderer<'a> { + surface: wgpu::Surface<'a>, + device: Arc, + queue: Arc, + surface_configuration: wgpu::SurfaceConfiguration, + sampler: wgpu::Sampler, + vertex_buffer: wgpu::Buffer, + index_buffer: wgpu::Buffer, + pipeline: wgpu::RenderPipeline, +} + +impl<'a> Renderer<'a> { + fn new(surface: wgpu::Surface<'a>, vulkan_device: &VulkanDevice, window: &Window) -> Self { + let device = vulkan_device.wgpu_device.clone(); + let queue = vulkan_device.wgpu_queue.clone(); + let size = window.inner_size(); + let surface_capabilities = surface.get_capabilities(&vulkan_device.wgpu_adapter); + let surface_texture_format = surface_capabilities + .formats + .iter() + .find(|f| f.is_srgb()) + .copied() + .unwrap_or(surface_capabilities.formats[0]); + + let surface_configuration = wgpu::SurfaceConfiguration { + usage: wgpu::TextureUsages::RENDER_ATTACHMENT, + width: size.width, + height: size.height, + format: surface_texture_format, + view_formats: vec![ + surface_texture_format, + surface_texture_format.remove_srgb_suffix(), + ], + alpha_mode: surface_capabilities.alpha_modes[0], + present_mode: surface_capabilities.present_modes[0], + desired_maximum_frame_latency: 2, + }; + + surface.configure(&device, &surface_configuration); + + let vertex_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("vertex buffer"), + usage: wgpu::BufferUsages::VERTEX, + contents: bytemuck::cast_slice(VERTICES), + }); + + let index_buffer = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { + label: Some("index buffer"), + usage: wgpu::BufferUsages::INDEX, + contents: bytemuck::cast_slice(INDICES), + }); + + let bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { + label: Some("bgl"), + entries: &[ + wgpu::BindGroupLayoutEntry { + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + binding: 0, + visibility: wgpu::ShaderStages::FRAGMENT, + }, + wgpu::BindGroupLayoutEntry { + ty: wgpu::BindingType::Texture { + sample_type: wgpu::TextureSampleType::Float { filterable: true }, + view_dimension: wgpu::TextureViewDimension::D2, + multisampled: false, + }, + count: None, + binding: 1, + visibility: wgpu::ShaderStages::FRAGMENT, + }, + wgpu::BindGroupLayoutEntry { + ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count: None, + binding: 2, + visibility: wgpu::ShaderStages::FRAGMENT, + }, + ], + }); + + let sampler = device.create_sampler(&wgpu::SamplerDescriptor { + label: Some("sampler"), + address_mode_u: wgpu::AddressMode::ClampToEdge, + address_mode_v: wgpu::AddressMode::ClampToEdge, + address_mode_w: wgpu::AddressMode::ClampToEdge, + mag_filter: wgpu::FilterMode::Nearest, + min_filter: wgpu::FilterMode::Nearest, + mipmap_filter: wgpu::FilterMode::Nearest, + ..Default::default() + }); + + let pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { + label: Some("pipeline layout"), + bind_group_layouts: &[&bind_group_layout], + push_constant_ranges: &[], + }); + + let shader_module_descriptor = wgpu::include_wgsl!("shader.wgsl"); + let shader_module = device.create_shader_module(shader_module_descriptor); + + let pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { + label: Some("render pipeline"), + layout: Some(&pipeline_layout), + cache: None, + vertex: wgpu::VertexState { + module: &shader_module, + buffers: &[Vertex::LAYOUT], + compilation_options: Default::default(), + entry_point: "vs_main", + }, + fragment: Some(wgpu::FragmentState { + module: &shader_module, + targets: &[Some(wgpu::ColorTargetState { + format: surface_configuration.format.remove_srgb_suffix(), + blend: Some(wgpu::BlendState::REPLACE), + write_mask: wgpu::ColorWrites::ALL, + })], + compilation_options: Default::default(), + entry_point: "fs_main", + }), + + primitive: wgpu::PrimitiveState { + topology: wgpu::PrimitiveTopology::TriangleList, + strip_index_format: None, + cull_mode: Some(wgpu::Face::Back), + front_face: wgpu::FrontFace::Ccw, + polygon_mode: wgpu::PolygonMode::Fill, + conservative: false, + unclipped_depth: false, + }, + multisample: wgpu::MultisampleState { + count: 1, + mask: !0, + alpha_to_coverage_enabled: false, + }, + multiview: None, + depth_stencil: None, + }); + + Self { + surface, + device, + queue, + surface_configuration, + sampler, + index_buffer, + vertex_buffer, + pipeline, + } + } + + fn resize(&mut self, size: PhysicalSize) { + if size.width > 0 && size.height > 0 { + self.surface_configuration.width = size.width; + self.surface_configuration.height = size.height; + self.surface + .configure(&self.device, &self.surface_configuration); + } + } + + fn render(&mut self, frame: &wgpu::Texture, window: &Window) -> Result<(), wgpu::SurfaceError> { + let device = &self.device; + let surface = self.surface.get_current_texture()?; + let surface_view = surface.texture.create_view(&wgpu::TextureViewDescriptor { + format: Some(surface.texture.format().remove_srgb_suffix()), + ..Default::default() + }); + let texture_view_y = frame.create_view(&wgpu::TextureViewDescriptor { + label: Some("y texture"), + format: Some(wgpu::TextureFormat::R8Unorm), + aspect: wgpu::TextureAspect::Plane0, + dimension: Some(wgpu::TextureViewDimension::D2), + ..Default::default() + }); + + let texture_view_uv = frame.create_view(&wgpu::TextureViewDescriptor { + label: Some("uv texture"), + format: Some(wgpu::TextureFormat::Rg8Unorm), + aspect: wgpu::TextureAspect::Plane1, + dimension: Some(wgpu::TextureViewDimension::D2), + ..Default::default() + }); + + let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { + label: Some("bind group"), + layout: &self.pipeline.get_bind_group_layout(0), + entries: &[ + wgpu::BindGroupEntry { + binding: 0, + resource: wgpu::BindingResource::TextureView(&texture_view_y), + }, + wgpu::BindGroupEntry { + binding: 1, + resource: wgpu::BindingResource::TextureView(&texture_view_uv), + }, + wgpu::BindGroupEntry { + binding: 2, + resource: wgpu::BindingResource::Sampler(&self.sampler), + }, + ], + }); + + let mut command_encoder = device.create_command_encoder(&Default::default()); + + { + let mut render_pass = command_encoder.begin_render_pass(&wgpu::RenderPassDescriptor { + label: Some("render pass"), + color_attachments: &[Some(wgpu::RenderPassColorAttachment { + view: &surface_view, + resolve_target: None, + ops: wgpu::Operations { + load: wgpu::LoadOp::Clear(wgpu::Color::WHITE), + store: wgpu::StoreOp::Store, + }, + })], + ..Default::default() + }); + + render_pass.set_pipeline(&self.pipeline); + render_pass.set_bind_group(0, &bind_group, &[]); + render_pass.set_vertex_buffer(0, self.vertex_buffer.slice(..)); + render_pass.set_index_buffer(self.index_buffer.slice(..), wgpu::IndexFormat::Uint16); + render_pass.draw_indexed(0..INDICES.len() as u32, 0, 0..1); + } + + self.queue.submit(Some(command_encoder.finish())); + window.pre_present_notify(); + surface.present(); + + Ok(()) + } +} diff --git a/vk-video/examples/player/player/shader.wgsl b/vk-video/examples/player/player/shader.wgsl new file mode 100644 index 000000000..1aa05c41c --- /dev/null +++ b/vk-video/examples/player/player/shader.wgsl @@ -0,0 +1,37 @@ +struct VertexInput { + @location(0) position: vec3, + @location(1) tex_coords: vec2, +} + +struct VertexOutput { + @builtin(position) position: vec4, + @location(0) tex_coords: vec2, +} + +@vertex +fn vs_main(input: VertexInput) -> VertexOutput { + var output: VertexOutput; + + output.position = vec4(input.position, 1.0); + output.tex_coords = input.tex_coords; + + return output; +} + +@group(0) @binding(0) var y_texture: texture_2d; +@group(0) @binding(1) var uv_texture: texture_2d; +@group(0) @binding(2) var sampler_: sampler; + +@fragment +fn fs_main(input: VertexOutput) -> @location(0) vec4 { + var y = textureSample(y_texture, sampler_, input.tex_coords).x; + var uv = textureSample(uv_texture, sampler_, input.tex_coords); + var u = uv.x; + var v = uv.y; + + let r = y + 1.40200 * (v - 128.0 / 255.0); + let g = y - 0.34414 * (u - 128.0 / 255.0) - 0.71414 * (v - 128.0 / 255.0); + let b = y + 1.77200 * (u - 128.0 / 255.0); + + return vec4(clamp(r, 0.0, 1.0), clamp(g, 0.0, 1.0), clamp(b, 0.0, 1.0), 1.0); +} diff --git a/vk-video/examples/wgpu.rs b/vk-video/examples/wgpu.rs index 36f52be03..6ef6346ad 100644 --- a/vk-video/examples/wgpu.rs +++ b/vk-video/examples/wgpu.rs @@ -2,6 +2,8 @@ fn main() { use std::io::Write; + use vk_video::{Frame, VulkanInstance}; + let subscriber = tracing_subscriber::FmtSubscriber::builder() .with_max_level(tracing::Level::INFO) .finish(); @@ -15,26 +17,28 @@ fn main() { } let h264_bytestream = std::fs::read(&args[1]).unwrap_or_else(|_| panic!("read {}", args[1])); - let vulkan_ctx = std::sync::Arc::new( - vk_video::VulkanCtx::new( + let vulkan_instance = VulkanInstance::new().unwrap(); + let vulkan_device = vulkan_instance + .create_device( wgpu::Features::empty(), wgpu::Limits { max_push_constant_size: 128, ..Default::default() }, + &mut None, ) - .unwrap(), - ); - let mut decoder = vk_video::Decoder::new(vulkan_ctx.clone()).unwrap(); + .unwrap(); + + let mut decoder = vulkan_device.create_wgpu_textures_decoder().unwrap(); let mut output_file = std::fs::File::create("output.nv12").unwrap(); for chunk in h264_bytestream.chunks(256) { - let frames = decoder.decode_to_wgpu_textures(chunk).unwrap(); + let frames = decoder.decode(chunk, None).unwrap(); - let device = &vulkan_ctx.wgpu_ctx.device; - let queue = &vulkan_ctx.wgpu_ctx.queue; - for frame in frames { + let device = &vulkan_device.wgpu_device; + let queue = &vulkan_device.wgpu_queue; + for Frame { frame, .. } in frames { let decoded_frame = download_wgpu_texture(device, queue, frame); output_file.write_all(&decoded_frame).unwrap(); } diff --git a/vk-video/src/lib.rs b/vk-video/src/lib.rs index 5826803b8..5948eed65 100644 --- a/vk-video/src/lib.rs +++ b/vk-video/src/lib.rs @@ -3,17 +3,10 @@ mod parser; mod vulkan_decoder; use parser::Parser; -use vulkan_decoder::VulkanDecoder; +use vulkan_decoder::{FrameSorter, VulkanDecoder}; pub use parser::ParserError; -pub use vulkan_decoder::{VulkanCtx, VulkanCtxError, VulkanDecoderError}; - -pub use vulkan_decoder::WgpuCtx; - -pub struct Decoder<'a> { - vulkan_decoder: VulkanDecoder<'a>, - parser: Parser, -} +pub use vulkan_decoder::{VulkanCtxError, VulkanDecoderError, VulkanDevice, VulkanInstance}; #[derive(Debug, thiserror::Error)] pub enum DecoderError { @@ -24,46 +17,65 @@ pub enum DecoderError { ParserError(#[from] ParserError), } -impl<'a> Decoder<'a> { - pub fn new(vulkan_ctx: std::sync::Arc) -> Result { - let parser = Parser::default(); - let vulkan_decoder = VulkanDecoder::new(vulkan_ctx)?; +pub struct Frame { + pub frame: T, + pub pts: Option, +} - Ok(Self { - parser, - vulkan_decoder, - }) - } +pub struct WgpuTexturesDeocder<'a> { + vulkan_decoder: VulkanDecoder<'a>, + parser: Parser, + frame_sorter: FrameSorter, } -impl Decoder<'_> { - /// The result is a [`Vec`] of [`Vec`]. Each [`Vec`] contains a single frame in the - /// NV12 format. - pub fn decode_to_bytes( +impl WgpuTexturesDeocder<'_> { + // TODO: the below hasn't been verified. + /// The produced textures have the [`wgpu::TextureFormat::NV12`] format and can be used as a copy source or a texture binding. + pub fn decode( &mut self, h264_bytestream: &[u8], - ) -> Result>, DecoderError> { - let instructions = self - .parser - .parse(h264_bytestream) - .into_iter() - .collect::, _>>()?; - - Ok(self.vulkan_decoder.decode_to_bytes(&instructions)?) + pts: Option, + ) -> Result>, DecoderError> { + let instructions = self.parser.parse(h264_bytestream, pts)?; + + let unsorted_frames = self.vulkan_decoder.decode_to_wgpu_textures(&instructions)?; + + let mut result = Vec::new(); + + for unsorted_frame in unsorted_frames { + let mut sorted_frames = self.frame_sorter.put(unsorted_frame); + result.append(&mut sorted_frames); + } + + Ok(result) } +} - // TODO: the below hasn't been verified. - /// The produced textures have the [`wgpu::TextureFormat::NV12`] format and can be used as a copy source or a texture binding. - pub fn decode_to_wgpu_textures( +pub struct BytesDecoder<'a> { + vulkan_decoder: VulkanDecoder<'a>, + parser: Parser, + frame_sorter: FrameSorter>, +} + +impl BytesDecoder<'_> { + /// The result is a sequence of frames. Te payload of each [`Frame`] struct is a [`Vec`]. Each [`Vec`] contains a single + /// decoded frame in the [NV12 format](https://en.wikipedia.org/wiki/YCbCr#4:2:0). + pub fn decode( &mut self, h264_bytestream: &[u8], - ) -> Result, DecoderError> { - let instructions = self - .parser - .parse(h264_bytestream) - .into_iter() - .collect::, _>>()?; - - Ok(self.vulkan_decoder.decode_to_wgpu_textures(&instructions)?) + pts: Option, + ) -> Result>>, DecoderError> { + let instructions = self.parser.parse(h264_bytestream, pts)?; + + let unsorted_frames = self.vulkan_decoder.decode_to_bytes(&instructions)?; + + let mut result = Vec::new(); + + for unsorted_frame in unsorted_frames { + let mut sorted_frames = self.frame_sorter.put(unsorted_frame); + result.append(&mut sorted_frames); + } + + Ok(result) } } diff --git a/vk-video/src/parser.rs b/vk-video/src/parser.rs index 622e86187..fce05ef5f 100644 --- a/vk-video/src/parser.rs +++ b/vk-video/src/parser.rs @@ -1,21 +1,22 @@ -use std::{ - io::Read, - sync::{mpsc, Arc}, -}; +use std::sync::{mpsc, Arc}; +use au_splitter::AUSplitter; use h264_reader::{ annexb::AnnexBReader, - nal::{pps::PicParameterSet, slice::SliceHeader, sps::SeqParameterSet, Nal, RefNal}, - push::{AccumulatedNalHandler, NalAccumulator, NalInterest}, + nal::{pps::PicParameterSet, slice::SliceHeader, sps::SeqParameterSet}, + push::NalAccumulator, }; -use reference_manager::ReferenceContext; -use tracing::trace; +use nalu_parser::{NalReceiver, ParsedNalu}; +use nalu_splitter::NALUSplitter; +use reference_manager::{ReferenceContext, ReferenceManagementError}; + +pub(crate) use reference_manager::ReferenceId; mod au_splitter; +mod nalu_parser; +mod nalu_splitter; mod reference_manager; -pub use reference_manager::{ReferenceId, ReferenceManagementError}; - #[derive(Clone, derivative::Derivative)] #[derivative(Debug)] #[allow(non_snake_case)] @@ -29,12 +30,17 @@ pub struct DecodeInformation { pub(crate) sps_id: u8, pub(crate) pps_id: u8, pub(crate) picture_info: PictureInfo, + pub(crate) pts: Option, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Copy)] +#[allow(non_snake_case)] pub(crate) struct ReferencePictureInfo { pub(crate) id: ReferenceId, - pub(crate) picture_info: PictureInfo, + pub(crate) LongTermPicNum: Option, + pub(crate) non_existing: bool, + pub(crate) FrameNum: u16, + pub(crate) PicOrderCnt: [i32; 2], } #[derive(Debug, Clone, Copy)] @@ -43,17 +49,14 @@ pub(crate) struct PictureInfo { pub(crate) used_for_long_term_reference: bool, pub(crate) non_existing: bool, pub(crate) FrameNum: u16, - pub(crate) PicOrderCnt: [i32; 2], + pub(crate) PicOrderCnt_for_decoding: [i32; 2], + pub(crate) PicOrderCnt_as_reference_pic: [i32; 2], } #[derive(Debug, Clone)] pub enum DecoderInstruction { Decode { decode_info: DecodeInformation, - }, - - DecodeAndStoreAs { - decode_info: DecodeInformation, reference_id: ReferenceId, }, @@ -95,213 +98,66 @@ pub enum ParserError { SliceParseError(h264_reader::nal::slice::SliceHeaderError), } -struct NalReceiver { - parser_ctx: h264_reader::Context, - au_splitter: au_splitter::AUSplitter, - reference_ctx: ReferenceContext, - debug_channel: mpsc::Sender, - decoder_channel: mpsc::Sender>, -} - -impl AccumulatedNalHandler for NalReceiver { - fn nal(&mut self, nal: RefNal<'_>) -> NalInterest { - if !nal.is_complete() { - return NalInterest::Buffer; - } - - match self.handle_nal(nal) { - Ok((debug_nalu, instructions)) => { - self.debug_channel.send(debug_nalu).unwrap(); - for instruction in instructions { - self.decoder_channel.send(Ok(instruction)).unwrap(); - } - } - - Err(err) => { - self.decoder_channel.send(Err(err)).unwrap(); - } - } - - NalInterest::Ignore - } -} - -impl NalReceiver { - fn handle_nal( - &mut self, - nal: RefNal<'_>, - ) -> Result<(NaluDebugInfo, Vec), ParserError> { - let nal_unit_type = nal - .header() - .map_err(ParserError::NalHeaderParseError)? - .nal_unit_type(); - - match nal_unit_type { - h264_reader::nal::UnitType::SeqParameterSet => { - let parsed = h264_reader::nal::sps::SeqParameterSet::from_bits(nal.rbsp_bits()) - .map_err(ParserError::SpsParseError)?; - - // Perhaps this shouldn't be here, but this is the only place we process sps - // before sending them to the decoder. It also seems that this is the only thing we - // need to check about the sps. - if parsed.gaps_in_frame_num_value_allowed_flag { - // TODO: what else to do here? sure we'll throw an error, but shouldn't we also - // terminate the parser somehow? - // perhaps this should be considered in other places we throw errors too - Err(ParserError::GapsInFrameNumNotSupported) - } else { - self.parser_ctx.put_seq_param_set(parsed.clone()); - Ok(( - NaluDebugInfo::Sps(parsed.clone()), - vec![DecoderInstruction::Sps(parsed)], - )) - } - } - - h264_reader::nal::UnitType::PicParameterSet => { - let parsed = h264_reader::nal::pps::PicParameterSet::from_bits( - &self.parser_ctx, - nal.rbsp_bits(), - ) - .map_err(ParserError::PpsParseError)?; - - self.parser_ctx.put_pic_param_set(parsed.clone()); - - Ok(( - NaluDebugInfo::Pps(parsed.clone()), - vec![DecoderInstruction::Pps(parsed)], - )) - } - - h264_reader::nal::UnitType::SliceLayerWithoutPartitioningNonIdr - | h264_reader::nal::UnitType::SliceLayerWithoutPartitioningIdr => { - let (header, sps, pps) = h264_reader::nal::slice::SliceHeader::from_bits( - &self.parser_ctx, - &mut nal.rbsp_bits(), - nal.header().unwrap(), - ) - .map_err(ParserError::SliceParseError)?; - - let header = Arc::new(header); - - let debug_nalu = match nal_unit_type { - h264_reader::nal::UnitType::SliceLayerWithoutPartitioningIdr => { - NaluDebugInfo::SliceWithoutPartitioningHeaderIdr(header.clone()) - } - h264_reader::nal::UnitType::SliceLayerWithoutPartitioningNonIdr => { - NaluDebugInfo::SliceWithoutPartitioningHeaderNonIdr(header.clone()) - } - _ => unreachable!(), - }; - - let mut rbsp_bytes = vec![0, 0, 0, 1]; - nal.reader().read_to_end(&mut rbsp_bytes).unwrap(); - let slice = Slice { - nal_header: nal.header().unwrap(), - header, - pps_id: pps.pic_parameter_set_id, - rbsp_bytes, - }; - - let Some(slices) = self.au_splitter.put_slice(slice) else { - return Ok((debug_nalu, Vec::new())); - }; - - let instructions = self.reference_ctx.put_picture(slices, sps, pps)?; - - Ok((debug_nalu, instructions)) - } - - h264_reader::nal::UnitType::Unspecified(_) - | h264_reader::nal::UnitType::SliceDataPartitionALayer - | h264_reader::nal::UnitType::SliceDataPartitionBLayer - | h264_reader::nal::UnitType::SliceDataPartitionCLayer - | h264_reader::nal::UnitType::SEI - | h264_reader::nal::UnitType::AccessUnitDelimiter - | h264_reader::nal::UnitType::EndOfSeq - | h264_reader::nal::UnitType::EndOfStream - | h264_reader::nal::UnitType::FillerData - | h264_reader::nal::UnitType::SeqParameterSetExtension - | h264_reader::nal::UnitType::PrefixNALUnit - | h264_reader::nal::UnitType::SubsetSeqParameterSet - | h264_reader::nal::UnitType::DepthParameterSet - | h264_reader::nal::UnitType::SliceLayerWithoutPartitioningAux - | h264_reader::nal::UnitType::SliceExtension - | h264_reader::nal::UnitType::SliceExtensionViewComponent - | h264_reader::nal::UnitType::Reserved(_) => Ok(( - NaluDebugInfo::Other(format!("{:?}", nal.header().unwrap().nal_unit_type())), - Vec::new(), - )), - } - } -} - -trait SpsExt { - fn max_frame_num(&self) -> i64; -} - -impl SpsExt for SeqParameterSet { - fn max_frame_num(&self) -> i64 { - 1 << self.log2_max_frame_num() - } -} - -#[derive(Debug)] -// this struct is only ever printed out in debug mode, but clippy detects this as it not being -// used. -#[allow(dead_code)] -pub enum NaluDebugInfo { - Sps(SeqParameterSet), - Pps(PicParameterSet), - SliceWithoutPartitioningHeaderNonIdr(Arc), - SliceWithoutPartitioningHeaderIdr(Arc), - Other(String), -} - -pub struct Slice { - pub nal_header: h264_reader::nal::NalHeader, - pub pps_id: h264_reader::nal::pps::PicParamSetId, - pub header: Arc, - pub rbsp_bytes: Vec, -} - pub struct Parser { reader: AnnexBReader>, - debug_channel: mpsc::Receiver, - decoder_channel: mpsc::Receiver>, + reference_ctx: ReferenceContext, + au_splitter: AUSplitter, + receiver: mpsc::Receiver>, + nalu_splitter: NALUSplitter, } impl Default for Parser { fn default() -> Self { - let (debug_tx, debug_rx) = mpsc::channel(); - let (decoder_tx, decoder_rx) = mpsc::channel(); + let (tx, rx) = mpsc::channel(); Parser { - reader: AnnexBReader::accumulate(NalReceiver { - reference_ctx: ReferenceContext::default(), - au_splitter: au_splitter::AUSplitter::default(), - debug_channel: debug_tx, - decoder_channel: decoder_tx, - parser_ctx: h264_reader::Context::new(), - }), - debug_channel: debug_rx, - decoder_channel: decoder_rx, + reader: AnnexBReader::accumulate(NalReceiver::new(tx)), + reference_ctx: ReferenceContext::default(), + au_splitter: AUSplitter::default(), + receiver: rx, + nalu_splitter: NALUSplitter::default(), } } } impl Parser { - pub fn parse(&mut self, bytes: &[u8]) -> Vec> { - self.reader.push(bytes); + pub fn parse( + &mut self, + bytes: &[u8], + pts: Option, + ) -> Result, ParserError> { + let nalus = self.nalu_splitter.push(bytes, pts); + let nalus = nalus + .into_iter() + .map(|(nalu, pts)| { + self.reader.push(&nalu); + (self.receiver.try_recv().unwrap(), pts) + }) + .collect::>(); let mut instructions = Vec::new(); - while let Ok(instruction) = self.decoder_channel.try_recv() { - instructions.push(instruction); - } - while let Ok(nalu) = self.debug_channel.try_recv() { - trace!("parsed nalu: {nalu:#?}"); + for (nalu, pts) in nalus { + let nalu = nalu?; + match nalu { + ParsedNalu::Sps(seq_parameter_set) => { + instructions.push(DecoderInstruction::Sps(seq_parameter_set)) + } + ParsedNalu::Pps(pic_parameter_set) => { + instructions.push(DecoderInstruction::Pps(pic_parameter_set)) + } + ParsedNalu::Slice(slice) => { + let Some(slices) = self.au_splitter.put_slice(slice, pts) else { + continue; + }; + + let mut inst = self.reference_ctx.put_picture(slices)?; + instructions.append(&mut inst); + } + + ParsedNalu::Other(_) => {} + } } - instructions + Ok(instructions) } } diff --git a/vk-video/src/parser/au_splitter.rs b/vk-video/src/parser/au_splitter.rs index ad46ffabd..5abf6018a 100644 --- a/vk-video/src/parser/au_splitter.rs +++ b/vk-video/src/parser/au_splitter.rs @@ -1,31 +1,35 @@ use h264_reader::nal::slice::PicOrderCountLsb; -use super::Slice; +use super::nalu_parser::Slice; #[derive(Default)] pub(crate) struct AUSplitter { - buffered_nals: Vec, + buffered_nals: Vec<(Slice, Option)>, } impl AUSplitter { - pub(crate) fn put_slice(&mut self, slice: Slice) -> Option> { + pub(crate) fn put_slice( + &mut self, + slice: Slice, + pts: Option, + ) -> Option)>> { if self.is_new_au(&slice) { let au = std::mem::take(&mut self.buffered_nals); - self.buffered_nals.push(slice); + self.buffered_nals.push((slice, pts)); if !au.is_empty() { Some(au) } else { None } } else { - self.buffered_nals.push(slice); + self.buffered_nals.push((slice, pts)); None } } /// returns `true` if `slice` is a first slice in an Access Unit fn is_new_au(&self, slice: &Slice) -> bool { - let Some(last) = self.buffered_nals.last() else { + let Some((last, _)) = self.buffered_nals.last() else { return true; }; @@ -46,20 +50,17 @@ impl AUSplitter { // defguardp first_mb_in_slice_zero(a) // when a.first_mb_in_slice == 0 and // a.nal_unit_type in [1, 2, 5] -// fn first_mb_in_slice_zero(slice: &Slice) -> bool { slice.header.first_mb_in_slice == 0 } // defguardp frame_num_differs(a, b) when a.frame_num != b.frame_num -// fn frame_num_differs(last: &Slice, curr: &Slice) -> bool { last.header.frame_num != curr.header.frame_num } // defguardp pic_parameter_set_id_differs(a, b) // when a.pic_parameter_set_id != b.pic_parameter_set_id -// fn pps_id_differs(last: &Slice, curr: &Slice) -> bool { last.pps_id != curr.pps_id } @@ -67,7 +68,6 @@ fn pps_id_differs(last: &Slice, curr: &Slice) -> bool { // defguardp field_pic_flag_differs(a, b) when a.field_pic_flag != b.field_pic_flag // // defguardp bottom_field_flag_differs(a, b) when a.bottom_field_flag != b.bottom_field_flag -// fn field_pic_flag_differs(last: &Slice, curr: &Slice) -> bool { last.header.field_pic != curr.header.field_pic } @@ -75,7 +75,6 @@ fn field_pic_flag_differs(last: &Slice, curr: &Slice) -> bool { // defguardp nal_ref_idc_differs_one_zero(a, b) // when (a.nal_ref_idc == 0 or b.nal_ref_idc == 0) and // a.nal_ref_idc != b.nal_ref_idc -// fn nal_ref_idc_differs_one_zero(last: &Slice, curr: &Slice) -> bool { (last.nal_header.nal_ref_idc() == 0 || curr.nal_header.nal_ref_idc() == 0) && last.nal_header.nal_ref_idc() != curr.nal_header.nal_ref_idc() @@ -85,7 +84,6 @@ fn nal_ref_idc_differs_one_zero(last: &Slice, curr: &Slice) -> bool { // when a.pic_order_cnt_type == 0 and b.pic_order_cnt_type == 0 and // (a.pic_order_cnt_lsb != b.pic_order_cnt_lsb or // a.delta_pic_order_cnt_bottom != b.delta_pic_order_cnt_bottom) -// fn pic_order_cnt_zero_check(last: &Slice, curr: &Slice) -> bool { let (last_pic_order_cnt_lsb, last_delta_pic_order_cnt_bottom) = match last.header.pic_order_cnt_lsb { @@ -111,20 +109,19 @@ fn pic_order_cnt_zero_check(last: &Slice, curr: &Slice) -> bool { || last_delta_pic_order_cnt_bottom != curr_delta_pic_order_cnt_bottom } +// TODO // defguardp pic_order_cnt_one_check_zero(a, b) // when a.pic_order_cnt_type == 1 and b.pic_order_cnt_type == 1 and // hd(a.delta_pic_order_cnt) != hd(b.delta_pic_order_cnt) -// TODO +// TODO // defguardp pic_order_cnt_one_check_one(a, b) // when a.pic_order_cnt_type == 1 and b.pic_order_cnt_type == 1 and // hd(hd(a.delta_pic_order_cnt)) != hd(hd(b.delta_pic_order_cnt)) -// TODO // defguardp idr_and_non_idr(a, b) // when (a.nal_unit_type == 5 or b.nal_unit_type == 5) and // a.nal_unit_type != b.nal_unit_type -// fn idr_and_non_idr(last: &Slice, curr: &Slice) -> bool { (last.nal_header.nal_unit_type().id() == 5) ^ (curr.nal_header.nal_unit_type().id() == 5) } diff --git a/vk-video/src/parser/nalu_parser.rs b/vk-video/src/parser/nalu_parser.rs new file mode 100644 index 000000000..3f188cd7c --- /dev/null +++ b/vk-video/src/parser/nalu_parser.rs @@ -0,0 +1,159 @@ +use std::{ + io::Read, + sync::{mpsc, Arc}, +}; + +use h264_reader::{ + nal::{pps::PicParameterSet, slice::SliceHeader, sps::SeqParameterSet, Nal, RefNal}, + push::{AccumulatedNalHandler, NalInterest}, + Context, +}; + +use super::ParserError; + +pub(crate) struct NalReceiver { + parser_ctx: h264_reader::Context, + sender: mpsc::Sender>, +} + +impl AccumulatedNalHandler for NalReceiver { + fn nal(&mut self, nal: RefNal<'_>) -> NalInterest { + if !nal.is_complete() { + return NalInterest::Buffer; + } + + let result = self.handle_nal(nal); + self.sender.send(result).unwrap(); + + NalInterest::Ignore + } +} + +impl NalReceiver { + pub(crate) fn new(sender: mpsc::Sender>) -> Self { + Self { + sender, + parser_ctx: Context::default(), + } + } + + fn handle_nal(&mut self, nal: RefNal<'_>) -> Result { + let nal_unit_type = nal + .header() + .map_err(ParserError::NalHeaderParseError)? + .nal_unit_type(); + + match nal_unit_type { + h264_reader::nal::UnitType::SeqParameterSet => { + let parsed = h264_reader::nal::sps::SeqParameterSet::from_bits(nal.rbsp_bits()) + .map_err(ParserError::SpsParseError)?; + + // Perhaps this shouldn't be here, but this is the only place we process sps + // before sending them to the decoder. It also seems that this is the only thing we + // need to check about the sps. + if parsed.gaps_in_frame_num_value_allowed_flag { + // TODO: what else to do here? sure we'll throw an error, but shouldn't we also + // terminate the parser somehow? + // perhaps this should be considered in other places we throw errors too + Err(ParserError::GapsInFrameNumNotSupported) + } else { + self.parser_ctx.put_seq_param_set(parsed.clone()); + Ok(ParsedNalu::Sps(parsed.clone())) + } + } + + h264_reader::nal::UnitType::PicParameterSet => { + let parsed = h264_reader::nal::pps::PicParameterSet::from_bits( + &self.parser_ctx, + nal.rbsp_bits(), + ) + .map_err(ParserError::PpsParseError)?; + + self.parser_ctx.put_pic_param_set(parsed.clone()); + + Ok(ParsedNalu::Pps(parsed.clone())) + } + + h264_reader::nal::UnitType::SliceLayerWithoutPartitioningNonIdr + | h264_reader::nal::UnitType::SliceLayerWithoutPartitioningIdr => { + let (header, sps, pps) = h264_reader::nal::slice::SliceHeader::from_bits( + &self.parser_ctx, + &mut nal.rbsp_bits(), + nal.header().unwrap(), + ) + .map_err(ParserError::SliceParseError)?; + + let header = Arc::new(header); + + let mut rbsp_bytes = vec![0, 0, 0, 1]; + nal.reader().read_to_end(&mut rbsp_bytes).unwrap(); + let slice = Slice { + nal_header: nal.header().unwrap(), + header, + pps_id: pps.pic_parameter_set_id, + rbsp_bytes, + sps: sps.clone(), + pps: pps.clone(), + }; + + Ok(ParsedNalu::Slice(slice)) + } + + h264_reader::nal::UnitType::Unspecified(_) + | h264_reader::nal::UnitType::SliceDataPartitionALayer + | h264_reader::nal::UnitType::SliceDataPartitionBLayer + | h264_reader::nal::UnitType::SliceDataPartitionCLayer + | h264_reader::nal::UnitType::SEI + | h264_reader::nal::UnitType::AccessUnitDelimiter + | h264_reader::nal::UnitType::EndOfSeq + | h264_reader::nal::UnitType::EndOfStream + | h264_reader::nal::UnitType::FillerData + | h264_reader::nal::UnitType::SeqParameterSetExtension + | h264_reader::nal::UnitType::PrefixNALUnit + | h264_reader::nal::UnitType::SubsetSeqParameterSet + | h264_reader::nal::UnitType::DepthParameterSet + | h264_reader::nal::UnitType::SliceLayerWithoutPartitioningAux + | h264_reader::nal::UnitType::SliceExtension + | h264_reader::nal::UnitType::SliceExtensionViewComponent + | h264_reader::nal::UnitType::Reserved(_) => Ok(ParsedNalu::Other(format!( + "{:?}", + nal.header().unwrap().nal_unit_type() + ))), + } + } +} + +pub(crate) trait SpsExt { + fn max_frame_num(&self) -> i64; +} + +impl SpsExt for SeqParameterSet { + fn max_frame_num(&self) -> i64 { + 1 << self.log2_max_frame_num() + } +} + +#[derive(Debug)] +// one variant of this enum is only ever printed out in debug mode, but clippy detects this as it not being +// used. +#[allow(dead_code)] +pub enum ParsedNalu { + Sps(SeqParameterSet), + Pps(PicParameterSet), + Slice(Slice), + Other(String), +} + +#[derive(derivative::Derivative)] +#[derivative(Debug)] +pub struct Slice { + pub nal_header: h264_reader::nal::NalHeader, + pub pps_id: h264_reader::nal::pps::PicParamSetId, + pub header: Arc, + #[derivative(Debug = "ignore")] + pub rbsp_bytes: Vec, + #[derivative(Debug = "ignore")] + pub sps: h264_reader::nal::sps::SeqParameterSet, + #[derivative(Debug = "ignore")] + pub pps: h264_reader::nal::pps::PicParameterSet, +} diff --git a/vk-video/src/parser/nalu_splitter.rs b/vk-video/src/parser/nalu_splitter.rs new file mode 100644 index 000000000..289b99950 --- /dev/null +++ b/vk-video/src/parser/nalu_splitter.rs @@ -0,0 +1,47 @@ +use bytes::{BufMut, BytesMut}; + +#[derive(Debug, Default)] +pub(crate) struct NALUSplitter { + buffer: BytesMut, + pts: Option, +} + +fn find_nalu_start_code(buf: &[u8]) -> Option { + if buf.is_empty() { + return None; + }; + + buf.windows(3) + .enumerate() + .filter(|(_, window)| **window == [0, 0, 1]) + .filter(|(i, window)| !(*i == 0 || (*i == 1 && window[0] == 0))) + .map(|(i, _)| i + 3) + .next() +} + +impl NALUSplitter { + pub(crate) fn push( + &mut self, + bytestream: &[u8], + pts: Option, + ) -> Vec<(Vec, Option)> { + let mut output_pts = if self.buffer.is_empty() { + pts + } else { + self.pts + }; + + self.buffer.put(bytestream); + let mut result = Vec::new(); + + while let Some(i) = find_nalu_start_code(&self.buffer) { + let nalu = self.buffer.split_to(i); + result.push((nalu.to_vec(), output_pts)); + output_pts = pts; + } + + self.pts = pts; + + result + } +} diff --git a/vk-video/src/parser/reference_manager.rs b/vk-video/src/parser/reference_manager.rs index 05ad2d4ad..a8a5dccfc 100644 --- a/vk-video/src/parser/reference_manager.rs +++ b/vk-video/src/parser/reference_manager.rs @@ -2,35 +2,23 @@ use std::sync::Arc; use h264_reader::nal::{ pps::PicParameterSet, - slice::{ - DecRefPicMarking, ModificationOfPicNums, NumRefIdxActive, RefPicListModifications, - SliceHeader, - }, + slice::{DecRefPicMarking, MemoryManagementControlOperation, SliceHeader}, sps::SeqParameterSet, }; use super::{ - DecodeInformation, DecoderInstruction, ParserError, PictureInfo, ReferencePictureInfo, Slice, - SpsExt, + nalu_parser::{Slice, SpsExt}, + DecodeInformation, DecoderInstruction, PictureInfo, ReferencePictureInfo, }; #[derive(Debug, thiserror::Error)] pub enum ReferenceManagementError { - #[error("B frames are not supported")] - BFramesNotSupported, - - #[error("Long-term references are not supported")] - LongTermRefsNotSupported, - #[error("SI frames are not supported")] SIFramesNotSupported, #[error("SP frames are not supported")] SPFramesNotSupported, - #[error("Adaptive memory control decoded reference picture marking process is not supported")] - AdaptiveMemCtlNotSupported, - #[error("PicOrderCntType {0} is not supperted")] PicOrderCntTypeNotSupported(u8), @@ -42,16 +30,27 @@ pub enum ReferenceManagementError { pub struct ReferenceId(usize); #[derive(Debug, Default)] +#[allow(non_snake_case)] pub(crate) struct ReferenceContext { pictures: ReferencePictures, next_reference_id: ReferenceId, - _previous_frame_num: usize, + previous_frame_num: usize, prev_pic_order_cnt_msb: i32, prev_pic_order_cnt_lsb: i32, + MaxLongTermFrameIdx: MaxLongTermFrameIdx, + prevFrameNumOffset: i64, + previous_picture_included_mmco_equal_5: bool, +} + +#[derive(Debug, Default)] +enum MaxLongTermFrameIdx { + #[default] + NoLongTermFrameIndices, + Idx(u64), } impl ReferenceContext { - fn get_next_reference_id(&mut self) -> ReferenceId { + fn next_reference_id(&mut self) -> ReferenceId { let result = self.next_reference_id; self.next_reference_id = ReferenceId(result.0 + 1); result @@ -61,18 +60,39 @@ impl ReferenceContext { *self = Self { pictures: ReferencePictures::default(), next_reference_id: ReferenceId::default(), - _previous_frame_num: 0, + previous_frame_num: 0, prev_pic_order_cnt_msb: 0, prev_pic_order_cnt_lsb: 0, + MaxLongTermFrameIdx: MaxLongTermFrameIdx::NoLongTermFrameIndices, + prevFrameNumOffset: 0, + previous_picture_included_mmco_equal_5: false, }; } + #[allow(non_snake_case)] + fn add_long_term_reference( + &mut self, + header: Arc, + LongTermFrameIdx: u64, + pic_order_cnt: [i32; 2], + ) -> ReferenceId { + let id = self.next_reference_id(); + self.pictures.long_term.push(LongTermReferencePicture { + header, + id, + LongTermFrameIdx, + pic_order_cnt, + }); + + id + } + fn add_short_term_reference( &mut self, header: Arc, pic_order_cnt: [i32; 2], ) -> ReferenceId { - let id = self.get_next_reference_id(); + let id = self.next_reference_id(); self.pictures.short_term.push(ShortTermReferencePicture { header, id, @@ -83,17 +103,18 @@ impl ReferenceContext { pub(crate) fn put_picture( &mut self, - mut slices: Vec, - sps: &SeqParameterSet, - pps: &PicParameterSet, - ) -> Result, ParserError> { - let header = slices.last().unwrap().header.clone(); + mut slices: Vec<(Slice, Option)>, + ) -> Result, ReferenceManagementError> { + let header = slices.last().unwrap().0.header.clone(); + let sps = slices.last().unwrap().0.sps.clone(); + let pps = slices.last().unwrap().0.pps.clone(); + let pts = slices.last().unwrap().1; // maybe this should be done in a different place, but if you think about it, there's not // really that many places to put this code in let mut rbsp_bytes = Vec::new(); let mut slice_indices = Vec::new(); - for slice in &mut slices { + for (slice, _) in &mut slices { if slice.rbsp_bytes.is_empty() { continue; } @@ -101,94 +122,331 @@ impl ReferenceContext { rbsp_bytes.append(&mut slice.rbsp_bytes); } - match header.dec_ref_pic_marking { + let decode_info = self.decode_information_for_frame( + header.clone(), + slice_indices, + rbsp_bytes, + &sps, + &pps, + pts, + )?; + + let decoder_instructions = match &header.clone().dec_ref_pic_marking { Some(DecRefPicMarking::Idr { long_term_reference_flag, .. - }) => { - if long_term_reference_flag { - Err(ReferenceManagementError::LongTermRefsNotSupported)?; - } - - let decode_info = self.decode_information_for_frame( + }) => self.reference_picture_marking_process_idr( + header.clone(), + decode_info, + *long_term_reference_flag, + )?, + + Some(DecRefPicMarking::SlidingWindow) => self + .reference_picture_marking_process_sliding_window( + &sps, header.clone(), - slice_indices, - rbsp_bytes, - sps, - pps, - )?; + decode_info, + )?, + Some(DecRefPicMarking::Adaptive(memory_management_control_operations)) => self + .reference_picture_marking_process_adaptive( + &sps, + header.clone(), + decode_info, + memory_management_control_operations, + )?, + + // this picture is not a reference + None => { + let reference_id = self.next_reference_id(); + vec![ + DecoderInstruction::Decode { + decode_info, + reference_id, + }, + DecoderInstruction::Drop { + reference_ids: vec![reference_id], + }, + ] + } + }; - self.reset_state(); + self.previous_picture_included_mmco_equal_5 = header.includes_mmco_equal_5(); - let reference_id = - self.add_short_term_reference(header, decode_info.picture_info.PicOrderCnt); + Ok(decoder_instructions) + } - Ok(vec![DecoderInstruction::Idr { - decode_info, - reference_id, - }]) + fn remove_long_term_ref( + &mut self, + long_term_frame_idx: u64, + ) -> Result { + for (i, frame) in self.pictures.long_term.iter().enumerate() { + if frame.LongTermFrameIdx == long_term_frame_idx { + return Ok(self.pictures.long_term.remove(i)); } + } - Some(DecRefPicMarking::SlidingWindow) => { - let num_short_term = self.pictures.short_term.len(); - let num_long_term = self.pictures.long_term.len(); + Err(ReferenceManagementError::IncorrectData( + format!("cannot remove long term reference with id {long_term_frame_idx}, because it does not exist") + )) + } - let decode_info = self.decode_information_for_frame( - header.clone(), - slice_indices, - rbsp_bytes, - sps, - pps, - )?; - let reference_id = self - .add_short_term_reference(header.clone(), decode_info.picture_info.PicOrderCnt); + #[allow(non_snake_case)] + fn remove_short_term_ref( + &mut self, + current_frame_num: i64, + sps: &SeqParameterSet, + pic_num_to_remove: i64, + ) -> Result { + for (i, picture) in self.pictures.short_term.iter().enumerate() { + let PicNum = decode_picture_numbers_for_short_term_ref( + picture.header.frame_num.into(), + current_frame_num, + sps, + ) + .PicNum; + + if PicNum == pic_num_to_remove { + return Ok(self.pictures.short_term.remove(i)); + } + } - let mut decoder_instructions = vec![DecoderInstruction::DecodeAndStoreAs { - decode_info, - reference_id, - }]; + Err(ReferenceManagementError::IncorrectData( + format!("cannot remove long term reference with pic num {pic_num_to_remove}, because it does not exist") + )) + } - if num_short_term + num_long_term == sps.max_num_ref_frames.max(1) as usize - && !self.pictures.short_term.is_empty() - { - let (idx, _) = self + fn reference_picture_marking_process_adaptive( + &mut self, + sps: &SeqParameterSet, + header: Arc, + decode_info: DecodeInformation, + memory_management_control_operations: &[MemoryManagementControlOperation], + ) -> Result, ReferenceManagementError> { + let mut decoder_instructions = Vec::new(); + + let mut new_long_term_frame_idx = None; + + for memory_management_control_operation in memory_management_control_operations { + match memory_management_control_operation { + MemoryManagementControlOperation::ShortTermUnusedForRef { + difference_of_pic_nums_minus1, + } => { + let pic_num_to_remove = + header.frame_num as i64 - (*difference_of_pic_nums_minus1 as i64 + 1); + + let removed = self.remove_short_term_ref( + header.frame_num.into(), + sps, + pic_num_to_remove, + )?; + + decoder_instructions.push(DecoderInstruction::Drop { + reference_ids: vec![removed.id], + }); + } + + MemoryManagementControlOperation::LongTermUnusedForRef { long_term_pic_num } => { + let removed = self.remove_long_term_ref(*long_term_pic_num as u64)?; + + decoder_instructions.push(DecoderInstruction::Drop { + reference_ids: vec![removed.id], + }); + } + + MemoryManagementControlOperation::ShortTermUsedForLongTerm { + difference_of_pic_nums_minus1, + long_term_frame_idx, + } => { + if let Ok(removed) = self.remove_long_term_ref(*long_term_frame_idx as u64) { + decoder_instructions.push(DecoderInstruction::Drop { + reference_ids: vec![removed.id], + }); + } + + let pic_num_to_remove = + header.frame_num as i64 - (*difference_of_pic_nums_minus1 as i64 + 1); + + let picture = self.remove_short_term_ref( + header.frame_num.into(), + sps, + pic_num_to_remove, + )?; + + self.pictures.long_term.push(LongTermReferencePicture { + header: picture.header, + LongTermFrameIdx: *long_term_frame_idx as u64, + pic_order_cnt: picture.pic_order_cnt, + id: picture.id, + }); + } + + MemoryManagementControlOperation::MaxUsedLongTermFrameRef { + max_long_term_frame_idx_plus1, + } => { + if *max_long_term_frame_idx_plus1 != 0 { + self.MaxLongTermFrameIdx = + MaxLongTermFrameIdx::Idx(*max_long_term_frame_idx_plus1 as u64 - 1); + } else { + self.MaxLongTermFrameIdx = MaxLongTermFrameIdx::NoLongTermFrameIndices; + } + + let max_idx = *max_long_term_frame_idx_plus1 as i128 - 1; + + let reference_ids_to_remove = self .pictures - .short_term + .long_term + .iter() + .filter(|p| p.LongTermFrameIdx as i128 > max_idx) + .map(|p| p.id) + .collect(); + + self.pictures.long_term = self + .pictures + .long_term .iter() - .enumerate() - .min_by_key(|(_, reference)| { - reference - .decode_picture_numbers(header.frame_num as i64, sps) - .unwrap() - .FrameNumWrap - }) - .unwrap(); + .filter(|p| p.LongTermFrameIdx as i128 <= max_idx) + .cloned() + .collect(); decoder_instructions.push(DecoderInstruction::Drop { - reference_ids: vec![self.pictures.short_term.remove(idx).id], + reference_ids: reference_ids_to_remove, }) } - Ok(decoder_instructions) + MemoryManagementControlOperation::AllRefPicturesUnused => { + let reference_ids = self + .pictures + .short_term + .drain(..) + .map(|p| p.id) + .chain(self.pictures.long_term.drain(..).map(|p| p.id)) + .collect(); + + self.MaxLongTermFrameIdx = MaxLongTermFrameIdx::NoLongTermFrameIndices; + + decoder_instructions.push(DecoderInstruction::Drop { reference_ids }) + } + MemoryManagementControlOperation::CurrentUsedForLongTerm { + long_term_frame_idx, + } => { + if let Ok(picture) = self.remove_long_term_ref(*long_term_frame_idx as u64) { + decoder_instructions.push(DecoderInstruction::Drop { + reference_ids: vec![picture.id], + }); + } + + new_long_term_frame_idx = Some(*long_term_frame_idx as u64); + } } + } + + let reference_id = match new_long_term_frame_idx { + Some(long_term_frame_idx) => self.add_long_term_reference( + header, + long_term_frame_idx, + decode_info.picture_info.PicOrderCnt_as_reference_pic, + ), + None => self.add_short_term_reference( + header, + decode_info.picture_info.PicOrderCnt_as_reference_pic, + ), + }; - Some(DecRefPicMarking::Adaptive(_)) => { - Err(ReferenceManagementError::AdaptiveMemCtlNotSupported)? + decoder_instructions.insert( + 0, + DecoderInstruction::Decode { + decode_info, + reference_id, + }, + ); + + if let MaxLongTermFrameIdx::Idx(max) = self.MaxLongTermFrameIdx { + if self.pictures.long_term.len() > max as usize + 1 { + return Err(ReferenceManagementError::IncorrectData(format!( + "there are {} long-term references, but there shouldn't be more than {max}", + self.pictures.long_term.len() + ))); } + } - // this picture is not a reference - None => Ok(vec![DecoderInstruction::Decode { - decode_info: self.decode_information_for_frame( - header, - slice_indices, - rbsp_bytes, - sps, - pps, - )?, - }]), + Ok(decoder_instructions) + } + + fn reference_picture_marking_process_sliding_window( + &mut self, + sps: &SeqParameterSet, + header: Arc, + decode_info: DecodeInformation, + ) -> Result, ReferenceManagementError> { + let num_short_term = self.pictures.short_term.len(); + let num_long_term = self.pictures.long_term.len(); + + let reference_id = self.add_short_term_reference( + header.clone(), + decode_info.picture_info.PicOrderCnt_as_reference_pic, + ); + + let mut decoder_instructions = vec![DecoderInstruction::Decode { + decode_info, + reference_id, + }]; + + if num_short_term + num_long_term == sps.max_num_ref_frames.max(1) as usize + && !self.pictures.short_term.is_empty() + { + let (idx, _) = self + .pictures + .short_term + .iter() + .enumerate() + .min_by_key(|(_, reference)| { + decode_picture_numbers_for_short_term_ref( + reference.header.frame_num.into(), + header.frame_num.into(), + sps, + ) + .FrameNumWrap + }) + .unwrap(); + + decoder_instructions.push(DecoderInstruction::Drop { + reference_ids: vec![self.pictures.short_term.remove(idx).id], + }) } + + Ok(decoder_instructions) } + fn reference_picture_marking_process_idr( + &mut self, + header: Arc, + decode_info: DecodeInformation, + long_term_reference_flag: bool, + ) -> Result, ReferenceManagementError> { + self.reset_state(); + + let reference_id = if long_term_reference_flag { + self.MaxLongTermFrameIdx = MaxLongTermFrameIdx::Idx(0); + self.add_long_term_reference( + header, + 0, + decode_info.picture_info.PicOrderCnt_as_reference_pic, + ) + } else { + self.MaxLongTermFrameIdx = MaxLongTermFrameIdx::NoLongTermFrameIndices; + self.add_short_term_reference( + header, + decode_info.picture_info.PicOrderCnt_as_reference_pic, + ) + }; + + Ok(vec![DecoderInstruction::Idr { + decode_info, + reference_id, + }]) + } + + #[allow(non_snake_case)] fn decode_information_for_frame( &mut self, header: Arc, @@ -196,62 +454,118 @@ impl ReferenceContext { rbsp_bytes: Vec, sps: &SeqParameterSet, pps: &PicParameterSet, - ) -> Result { - let reference_list = match header.slice_type.family { - h264_reader::nal::slice::SliceFamily::P => { - let mut reference_list = - self.initialize_reference_picture_list_for_frame(&header, sps, pps)?; - - match &header.ref_pic_list_modification { - Some(RefPicListModifications::P { - ref_pic_list_modification_l0, - }) => { - self.modify_reference_picture_list( - sps, - &header, - &mut reference_list, - ref_pic_list_modification_l0, - )?; - } - - None - | Some(RefPicListModifications::I) - | Some(RefPicListModifications::B { .. }) => return Err(ReferenceManagementError::IncorrectData( - "a slice marked 'P' slice family contains a reference picture list for a different family".into() - ))?, - } + pts: Option, + ) -> Result { + let PicOrderCnt_for_decoding = self.decode_pic_order_cnt(&header, sps)?; + let PicOrderCnt_as_reference_pic = if header.includes_mmco_equal_5() { + [0, 0] + } else { + PicOrderCnt_for_decoding + }; - Some(reference_list) + let reference_list = match header.slice_type.family { + h264_reader::nal::slice::SliceFamily::P | h264_reader::nal::slice::SliceFamily::B => { + Some(self.reference_list_for_frame(&header, sps)?) } h264_reader::nal::slice::SliceFamily::I => None, - h264_reader::nal::slice::SliceFamily::B => { - return Err(ReferenceManagementError::BFramesNotSupported)? - } h264_reader::nal::slice::SliceFamily::SP => { - return Err(ReferenceManagementError::SPFramesNotSupported)? + return Err(ReferenceManagementError::SPFramesNotSupported) } h264_reader::nal::slice::SliceFamily::SI => { - return Err(ReferenceManagementError::SIFramesNotSupported)? + return Err(ReferenceManagementError::SIFramesNotSupported) } }; - let pic_order_cnt = match sps.pic_order_cnt { + Ok(DecodeInformation { + reference_list, + header: header.clone(), + slice_indices, + rbsp_bytes, + sps_id: sps.id().id(), + pps_id: pps.pic_parameter_set_id.id(), + picture_info: PictureInfo { + non_existing: false, + used_for_long_term_reference: false, + PicOrderCnt_for_decoding, + PicOrderCnt_as_reference_pic, + FrameNum: header.frame_num, + }, + pts, + }) + } + + fn decode_pic_order_cnt( + &mut self, + header: &SliceHeader, + sps: &SeqParameterSet, + ) -> Result<[i32; 2], ReferenceManagementError> { + match sps.pic_order_cnt { h264_reader::nal::sps::PicOrderCntType::TypeZero { log2_max_pic_order_cnt_lsb_minus4, - } => { - // this section is very hard to read, but all of this code is just copied from the - // h.264 spec, where it looks almost exactly like this + } => self.decode_pic_order_cnt_type_zero(header, log2_max_pic_order_cnt_lsb_minus4), + + h264_reader::nal::sps::PicOrderCntType::TypeOne { .. } => { + Err(ReferenceManagementError::PicOrderCntTypeNotSupported(1)) + } - let max_pic_order_cnt_lsb = 2_i32.pow(log2_max_pic_order_cnt_lsb_minus4 as u32 + 4); + h264_reader::nal::sps::PicOrderCntType::TypeTwo => { + self.decode_pic_order_cnt_type_two(header, sps) + } + } + } - let (prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb) = - if header.idr_pic_id.is_some() { - (0, 0) - } else { - (self.prev_pic_order_cnt_msb, self.prev_pic_order_cnt_lsb) - }; + #[allow(non_snake_case)] + fn decode_pic_order_cnt_type_two( + &mut self, + header: &SliceHeader, + sps: &SeqParameterSet, + ) -> Result<[i32; 2], ReferenceManagementError> { + let FrameNumOffset = if header.idr_pic_id.is_some() { + 0 + } else { + let prevFrameNumOffset = if self.previous_picture_included_mmco_equal_5 { + 0 + } else { + self.prevFrameNumOffset + }; + + if self.previous_frame_num > header.frame_num.into() { + prevFrameNumOffset + sps.max_frame_num() + } else { + prevFrameNumOffset + } + }; + + let tempPicOrderCnt = if header.idr_pic_id.is_some() { + 0 + } else if header.dec_ref_pic_marking.is_none() { + 2 * (FrameNumOffset as i32 + header.frame_num as i32) - 1 + } else { + 2 * (FrameNumOffset as i32 + header.frame_num as i32) + }; + + self.prevFrameNumOffset = FrameNumOffset; + + Ok([tempPicOrderCnt; 2]) + } + + fn decode_pic_order_cnt_type_zero( + &mut self, + header: &SliceHeader, + log2_max_pic_order_cnt_lsb_minus4: u8, + ) -> Result<[i32; 2], ReferenceManagementError> { + // this section is very hard to read, but all of this code is just copied from the + // h.264 spec, where it looks almost exactly like this + + let max_pic_order_cnt_lsb = 2_i32.pow(log2_max_pic_order_cnt_lsb_minus4 as u32 + 4); - let (pic_order_cnt_lsb, delta_pic_order_cnt_bottom) = match header + let (prev_pic_order_cnt_msb, prev_pic_order_cnt_lsb) = if header.idr_pic_id.is_some() { + (0, 0) + } else { + (self.prev_pic_order_cnt_msb, self.prev_pic_order_cnt_lsb) + }; + + let (pic_order_cnt_lsb, delta_pic_order_cnt_bottom) = match header .pic_order_cnt_lsb .as_ref() .ok_or(ReferenceManagementError::IncorrectData("pic_order_cnt_lsb is not present in a slice header, but is required for decoding".into()))? @@ -268,254 +582,91 @@ impl ReferenceContext { } }; - let pic_order_cnt_lsb = pic_order_cnt_lsb as i32; - - let pic_order_cnt_msb = if pic_order_cnt_lsb < prev_pic_order_cnt_lsb - && prev_pic_order_cnt_lsb - pic_order_cnt_lsb >= max_pic_order_cnt_lsb / 2 - { - prev_pic_order_cnt_msb + max_pic_order_cnt_lsb - } else if pic_order_cnt_lsb > prev_pic_order_cnt_lsb - && pic_order_cnt_lsb - prev_pic_order_cnt_lsb > max_pic_order_cnt_lsb / 2 - { - prev_pic_order_cnt_msb - max_pic_order_cnt_lsb - } else { - prev_pic_order_cnt_msb - }; - - let pic_order_cnt = if header.field_pic == h264_reader::nal::slice::FieldPic::Frame - { - let top_field_order_cnt = pic_order_cnt_msb + pic_order_cnt_lsb; + let pic_order_cnt_lsb = pic_order_cnt_lsb as i32; - let bottom_field_order_cnt = top_field_order_cnt + delta_pic_order_cnt_bottom; - - top_field_order_cnt.min(bottom_field_order_cnt) - } else { - pic_order_cnt_msb + pic_order_cnt_lsb - }; - - self.prev_pic_order_cnt_msb = pic_order_cnt_msb; - self.prev_pic_order_cnt_lsb = pic_order_cnt_lsb; + let pic_order_cnt_msb = if pic_order_cnt_lsb < prev_pic_order_cnt_lsb + && prev_pic_order_cnt_lsb - pic_order_cnt_lsb >= max_pic_order_cnt_lsb / 2 + { + prev_pic_order_cnt_msb + max_pic_order_cnt_lsb + } else if pic_order_cnt_lsb > prev_pic_order_cnt_lsb + && pic_order_cnt_lsb - prev_pic_order_cnt_lsb > max_pic_order_cnt_lsb / 2 + { + prev_pic_order_cnt_msb - max_pic_order_cnt_lsb + } else { + prev_pic_order_cnt_msb + }; - pic_order_cnt - } + let pic_order_cnt = if header.field_pic == h264_reader::nal::slice::FieldPic::Frame { + let top_field_order_cnt = pic_order_cnt_msb + pic_order_cnt_lsb; - h264_reader::nal::sps::PicOrderCntType::TypeOne { .. } => { - Err(ReferenceManagementError::PicOrderCntTypeNotSupported(1))? - } + let bottom_field_order_cnt = top_field_order_cnt + delta_pic_order_cnt_bottom; - h264_reader::nal::sps::PicOrderCntType::TypeTwo => match header.dec_ref_pic_marking { - None => 2 * header.frame_num as i32 - 1, - Some(DecRefPicMarking::Idr { .. }) | Some(DecRefPicMarking::SlidingWindow) => { - 2 * header.frame_num as i32 - } - Some(DecRefPicMarking::Adaptive(..)) => { - Err(ReferenceManagementError::AdaptiveMemCtlNotSupported)? - } - }, + top_field_order_cnt.min(bottom_field_order_cnt) + } else { + pic_order_cnt_msb + pic_order_cnt_lsb }; - let pic_order_cnt = [pic_order_cnt; 2]; + self.prev_pic_order_cnt_msb = pic_order_cnt_msb; + self.prev_pic_order_cnt_lsb = pic_order_cnt_lsb; - Ok(DecodeInformation { - reference_list, - header: header.clone(), - slice_indices, - rbsp_bytes, - sps_id: sps.id().id(), - pps_id: pps.pic_parameter_set_id.id(), - picture_info: PictureInfo { - non_existing: false, - used_for_long_term_reference: false, - PicOrderCnt: pic_order_cnt, - FrameNum: header.frame_num, - }, - }) + Ok([pic_order_cnt; 2]) } - fn initialize_short_term_reference_picture_list_for_frame( + fn short_term_reference_list_for_frame( &self, header: &SliceHeader, sps: &SeqParameterSet, - ) -> Result, ParserError> { - let mut short_term_reference_list = self - .pictures + ) -> Vec { + self.pictures .short_term .iter() .map(|reference| { - Ok(( - reference, - reference.decode_picture_numbers(header.frame_num.into(), sps)?, - )) - }) - .collect::, ParserError>>()?; - - short_term_reference_list.sort_by_key(|(_, numbers)| -numbers.PicNum); - - let short_term_reference_list = short_term_reference_list - .into_iter() - .map(|(reference, numbers)| ReferencePictureInfo { - id: reference.id, - picture_info: PictureInfo { + let numbers = decode_picture_numbers_for_short_term_ref( + reference.header.frame_num.into(), + header.frame_num.into(), + sps, + ); + ReferencePictureInfo { + id: reference.id, + LongTermPicNum: None, FrameNum: numbers.FrameNum as u16, - used_for_long_term_reference: false, non_existing: false, PicOrderCnt: reference.pic_order_cnt, - }, + } }) - .collect::>(); - - Ok(short_term_reference_list) + .collect() } - fn initialize_long_term_reference_picture_list_for_frame( - &self, - ) -> Result, ReferenceManagementError> { - if !self.pictures.long_term.is_empty() { - panic!("long-term references are not supported!"); - } - - Ok(Vec::new()) + fn long_term_reference_list_for_frame(&self) -> Vec { + self.pictures + .long_term + .iter() + .map(|pic| ReferencePictureInfo { + id: pic.id, + LongTermPicNum: Some(pic.LongTermFrameIdx), + PicOrderCnt: pic.pic_order_cnt, + non_existing: false, + FrameNum: pic.header.frame_num, + }) + .collect() } - fn initialize_reference_picture_list_for_frame( + fn reference_list_for_frame( &self, header: &SliceHeader, sps: &SeqParameterSet, - pps: &PicParameterSet, - ) -> Result, ParserError> { - let num_ref_idx_l0_active = header - .num_ref_idx_active - .as_ref() - .map(|num| match num { - NumRefIdxActive::P { - num_ref_idx_l0_active_minus1, - } => Ok(*num_ref_idx_l0_active_minus1), - NumRefIdxActive::B { .. } => Err(ReferenceManagementError::BFramesNotSupported), - }) - .unwrap_or(Ok(pps.num_ref_idx_l0_default_active_minus1))? - + 1; - - let short_term_reference_list = - self.initialize_short_term_reference_picture_list_for_frame(header, sps)?; + ) -> Result, ReferenceManagementError> { + let short_term_reference_list = self.short_term_reference_list_for_frame(header, sps); - let long_term_reference_list = - self.initialize_long_term_reference_picture_list_for_frame()?; + let long_term_reference_list = self.long_term_reference_list_for_frame(); - let mut reference_list = short_term_reference_list + let reference_list = short_term_reference_list .into_iter() .chain(long_term_reference_list) - .collect::>(); - - reference_list.truncate(num_ref_idx_l0_active as usize); + .collect(); Ok(reference_list) } - - #[allow(non_snake_case)] - fn modify_reference_picture_list( - &self, - sps: &SeqParameterSet, - header: &SliceHeader, - reference_list: &mut Vec, - ref_pic_list_modifications: &[ModificationOfPicNums], - ) -> Result<(), ReferenceManagementError> { - // 0 is Subtract, 1 is Add, 2 is LongTermRef - let mut refIdxL0 = 0; - let mut picNumL0Pred = header.frame_num as i64; - - for ref_pic_list_modification in ref_pic_list_modifications { - match ref_pic_list_modification { - ModificationOfPicNums::Subtract(_) | ModificationOfPicNums::Add(_) => { - self.modify_short_term_reference_picture_list( - sps, - header, - reference_list, - ref_pic_list_modification, - &mut refIdxL0, - &mut picNumL0Pred, - )?; - } - - ModificationOfPicNums::LongTermRef(_) => { - return Err(ReferenceManagementError::LongTermRefsNotSupported) - } - } - } - - Ok(()) - } - - #[allow(non_snake_case)] - fn modify_short_term_reference_picture_list( - &self, - sps: &SeqParameterSet, - header: &SliceHeader, - reference_list: &mut Vec, - ref_pic_list_modification: &ModificationOfPicNums, - refIdxLX: &mut usize, - picNumLXPred: &mut i64, - ) -> Result<(), ReferenceManagementError> { - let picNumLXNoWrap = match *ref_pic_list_modification { - ModificationOfPicNums::Subtract(abs_diff_pic_num_minus_1) => { - let abs_diff_pic_num = abs_diff_pic_num_minus_1 as i64 + 1; - if *picNumLXPred - abs_diff_pic_num < 0 { - *picNumLXPred - abs_diff_pic_num + sps.max_frame_num() - } else { - *picNumLXPred - abs_diff_pic_num - } - } - ModificationOfPicNums::Add(abs_diff_pic_num_minus_1) => { - let abs_diff_pic_num = abs_diff_pic_num_minus_1 as i64 + 1; - if *picNumLXPred + abs_diff_pic_num >= sps.max_frame_num() { - *picNumLXPred + abs_diff_pic_num - sps.max_frame_num() - } else { - *picNumLXPred + abs_diff_pic_num - } - } - ModificationOfPicNums::LongTermRef(_) => return Ok(()), - }; - - *picNumLXPred = picNumLXNoWrap; - - let picNumLX = if picNumLXNoWrap > header.frame_num as i64 { - picNumLXNoWrap - sps.max_frame_num() - } else { - picNumLXNoWrap - }; - - let shifted_picture_idx = reference_list - .iter() - .enumerate() - .find(|(_, picture_info)| picture_info.picture_info.FrameNum as i64 == picNumLX) - .map(|(i, _)| i) - .ok_or(ReferenceManagementError::IncorrectData( - format!("picture with picNumLX = {picNumLX} is not present in the reference list during modification") - ))?; - - if reference_list[shifted_picture_idx] - .picture_info - .non_existing - { - return Err(ReferenceManagementError::IncorrectData( - "a short-term reference picture marked for shifting in the reference list modification process is marked as non-existing".into() - )); - } - - if reference_list[shifted_picture_idx] - .picture_info - .used_for_long_term_reference - { - return Err(ReferenceManagementError::IncorrectData( - "a long-term reference picture marked for shifting in the short-term reference list modification process".into() - )); - } - - let shifted_picture_info = reference_list.remove(shifted_picture_idx); - reference_list.insert(*refIdxLX, shifted_picture_info); - *refIdxLX += 1; - - Ok(()) - } } #[derive(Debug)] @@ -525,42 +676,39 @@ struct ShortTermReferencePicture { pic_order_cnt: [i32; 2], } -impl ShortTermReferencePicture { - #[allow(non_snake_case)] - fn decode_picture_numbers( - &self, - current_frame_num: i64, - sps: &SeqParameterSet, - ) -> Result { - if self.header.field_pic != h264_reader::nal::slice::FieldPic::Frame { - return Err(ParserError::FieldsNotSupported); - } - - let MaxFrameNum = sps.max_frame_num(); - - let FrameNum = self.header.frame_num as i64; - - let FrameNumWrap = if FrameNum > current_frame_num { - FrameNum - MaxFrameNum - } else { - FrameNum - }; - - // this assumes we're dealing with a short-term reference frame - let PicNum = FrameNumWrap; - - Ok(ShortTermReferencePictureNumbers { - FrameNum, - FrameNumWrap, - PicNum, - }) +#[allow(non_snake_case)] +fn decode_picture_numbers_for_short_term_ref( + frame_num: i64, + current_frame_num: i64, + sps: &SeqParameterSet, +) -> ShortTermReferencePictureNumbers { + let MaxFrameNum = sps.max_frame_num(); + + let FrameNum = frame_num; + + let FrameNumWrap = if FrameNum > current_frame_num { + FrameNum - MaxFrameNum + } else { + FrameNum + }; + + // this assumes we're dealing with a short-term reference frame + let PicNum = FrameNumWrap; + + ShortTermReferencePictureNumbers { + FrameNum, + FrameNumWrap, + PicNum, } } -#[derive(Debug)] +#[derive(Debug, Clone)] +#[allow(non_snake_case)] struct LongTermReferencePicture { - _header: Arc, - _id: ReferenceId, + header: Arc, + LongTermFrameIdx: u64, + id: ReferenceId, + pic_order_cnt: [i32; 2], } #[allow(non_snake_case)] @@ -577,3 +725,19 @@ struct ReferencePictures { long_term: Vec, short_term: Vec, } + +trait SliceHeaderExt { + fn includes_mmco_equal_5(&self) -> bool; +} + +impl SliceHeaderExt for SliceHeader { + fn includes_mmco_equal_5(&self) -> bool { + let Some(DecRefPicMarking::Adaptive(ref mmcos)) = self.dec_ref_pic_marking else { + return false; + }; + + mmcos + .iter() + .any(|mmco| matches!(mmco, MemoryManagementControlOperation::AllRefPicturesUnused)) + } +} diff --git a/vk-video/src/vulkan_decoder.rs b/vk-video/src/vulkan_decoder.rs index f2152e472..84ffdccd5 100644 --- a/vk-video/src/vulkan_decoder.rs +++ b/vk-video/src/vulkan_decoder.rs @@ -9,20 +9,21 @@ use wrappers::*; use crate::parser::{DecodeInformation, DecoderInstruction, ReferenceId}; +mod frame_sorter; mod session_resources; mod vulkan_ctx; mod wrappers; +pub(crate) use frame_sorter::FrameSorter; pub use vulkan_ctx::*; pub struct VulkanDecoder<'a> { - vulkan_ctx: Arc, + vulkan_device: Arc, video_session_resources: Option>, command_buffers: CommandBuffers, _command_pools: CommandPools, sync_structures: SyncStructures, reference_id_to_dpb_slot_index: std::collections::HashMap, - decode_query_pool: Option, } struct SyncStructures { @@ -39,13 +40,17 @@ struct CommandBuffers { /// this cannot outlive the image and semaphore it borrows, but it seems impossible to encode that /// in the lifetimes -struct DecodeOutput { +struct DecodeSubmission { image: vk::Image, dimensions: vk::Extent2D, current_layout: vk::ImageLayout, layer: u32, wait_semaphore: vk::Semaphore, _input_buffer: Buffer, + picture_order_cnt: i32, + max_num_reorder_frames: u64, + is_idr: bool, + pts: Option, } #[derive(Debug, thiserror::Error)] @@ -80,12 +85,21 @@ pub enum VulkanDecoderError { #[error("A vulkan decode operation failed with code {0:?}")] DecodeOperationFailed(vk::QueryResultStatusKHR), + #[error("Invalid input data for the decoder: {0}.")] + InvalidInputData(String), + + #[error("Profile changed during the stream")] + ProfileChangeUnsupported, + + #[error("Level changed during the stream")] + LevelChangeUnsupported, + #[error(transparent)] VulkanCtxError(#[from] VulkanCtxError), } impl<'a> VulkanDecoder<'a> { - pub fn new(vulkan_ctx: Arc) -> Result { + pub fn new(vulkan_ctx: Arc) -> Result { let decode_pool = Arc::new(CommandPool::new( vulkan_ctx.device.clone(), vulkan_ctx.queues.h264_decode.idx, @@ -113,21 +127,8 @@ impl<'a> VulkanDecoder<'a> { fence_memory_barrier_completed: Fence::new(vulkan_ctx.device.clone(), false)?, }; - let decode_query_pool = if vulkan_ctx - .queues - .h264_decode - .supports_result_status_queries() - { - Some(DecodeQueryPool::new( - vulkan_ctx.device.clone(), - H264ProfileInfo::decode_h264_yuv420().profile_info, - )?) - } else { - None - }; - Ok(Self { - vulkan_ctx, + vulkan_device: vulkan_ctx, video_session_resources: None, _command_pools: command_pools, command_buffers: CommandBuffers { @@ -136,21 +137,34 @@ impl<'a> VulkanDecoder<'a> { vulkan_to_wgpu_transfer_buffer, }, sync_structures, - decode_query_pool, reference_id_to_dpb_slot_index: Default::default(), }) } } +pub(crate) struct DecodeResult { + frame: T, + pts: Option, + pic_order_cnt: i32, + max_num_reorder_frames: u64, + is_idr: bool, +} + impl VulkanDecoder<'_> { pub fn decode_to_bytes( &mut self, decoder_instructions: &[DecoderInstruction], - ) -> Result>, VulkanDecoderError> { + ) -> Result>>, VulkanDecoderError> { let mut result = Vec::new(); for instruction in decoder_instructions { if let Some(output) = self.decode(instruction)? { - result.push(self.download_output(output)?) + result.push(DecodeResult { + pts: output.pts, + is_idr: output.is_idr, + max_num_reorder_frames: output.max_num_reorder_frames, + pic_order_cnt: output.picture_order_cnt, + frame: self.download_output(output)?, + }) } } @@ -160,11 +174,17 @@ impl VulkanDecoder<'_> { pub fn decode_to_wgpu_textures( &mut self, decoder_instructions: &[DecoderInstruction], - ) -> Result, VulkanDecoderError> { + ) -> Result>, VulkanDecoderError> { let mut result = Vec::new(); for instruction in decoder_instructions { if let Some(output) = self.decode(instruction)? { - result.push(self.output_to_wgpu_texture(output)?) + result.push(DecodeResult { + pts: output.pts, + is_idr: output.is_idr, + max_num_reorder_frames: output.max_num_reorder_frames, + pic_order_cnt: output.picture_order_cnt, + frame: self.output_to_wgpu_texture(output)?, + }) } } @@ -174,20 +194,14 @@ impl VulkanDecoder<'_> { fn decode( &mut self, instruction: &DecoderInstruction, - ) -> Result, VulkanDecoderError> { + ) -> Result, VulkanDecoderError> { match instruction { - DecoderInstruction::Decode { .. } => { - return Err(VulkanDecoderError::DecoderInstructionNotSupported( - Box::new(instruction.clone()), - )) - } - - DecoderInstruction::DecodeAndStoreAs { + DecoderInstruction::Decode { decode_info, reference_id, } => { return self - .process_reference_p_frame(decode_info, *reference_id) + .process_reference_p_or_b_frame(decode_info, *reference_id) .map(Option::Some) } @@ -223,16 +237,16 @@ impl VulkanDecoder<'_> { fn process_sps(&mut self, sps: &SeqParameterSet) -> Result<(), VulkanDecoderError> { match self.video_session_resources.as_mut() { Some(session) => session.process_sps( - &self.vulkan_ctx, + &self.vulkan_device, &self.command_buffers.decode_buffer, - sps, + sps.clone(), &self.sync_structures.fence_memory_barrier_completed, )?, None => { self.video_session_resources = Some(VideoSessionResources::new_from_sps( - &self.vulkan_ctx, + &self.vulkan_device, &self.command_buffers.decode_buffer, - sps, + sps.clone(), &self.sync_structures.fence_memory_barrier_completed, )?) } @@ -245,7 +259,7 @@ impl VulkanDecoder<'_> { self.video_session_resources .as_mut() .ok_or(VulkanDecoderError::NoSession)? - .process_pps(pps)?; + .process_pps(pps.clone())?; Ok(()) } @@ -262,15 +276,15 @@ impl VulkanDecoder<'_> { &mut self, decode_information: &DecodeInformation, reference_id: ReferenceId, - ) -> Result { + ) -> Result { self.do_decode(decode_information, reference_id, true, true) } - fn process_reference_p_frame( + fn process_reference_p_or_b_frame( &mut self, decode_information: &DecodeInformation, reference_id: ReferenceId, - ) -> Result { + ) -> Result { self.do_decode(decode_information, reference_id, false, true) } @@ -280,27 +294,28 @@ impl VulkanDecoder<'_> { reference_id: ReferenceId, is_idr: bool, is_reference: bool, - ) -> Result { + ) -> Result { // upload data to a buffer let size = Self::pad_size_to_alignment( decode_information.rbsp_bytes.len() as u64, - self.vulkan_ctx + self.vulkan_device .video_capabilities .min_bitstream_buffer_offset_alignment, ); - let decode_buffer = Buffer::new_with_decode_data( - self.vulkan_ctx.allocator.clone(), - &decode_information.rbsp_bytes, - size, - )?; - // decode let video_session_resources = self .video_session_resources .as_mut() .ok_or(VulkanDecoderError::NoSession)?; + let decode_buffer = Buffer::new_with_decode_data( + self.vulkan_device.allocator.clone(), + &decode_information.rbsp_bytes, + size, + &video_session_resources.profile_info, + )?; + // IDR - remove all reference picures if is_idr { video_session_resources @@ -322,13 +337,13 @@ impl VulkanDecoder<'_> { ); unsafe { - self.vulkan_ctx.device.cmd_pipeline_barrier2( + self.vulkan_device.device.cmd_pipeline_barrier2( *self.command_buffers.decode_buffer, &vk::DependencyInfo::default().memory_barriers(&[memory_barrier]), ) }; - if let Some(pool) = self.decode_query_pool.as_ref() { + if let Some(pool) = video_session_resources.decode_query_pool.as_ref() { pool.reset(*self.command_buffers.decode_buffer); } @@ -342,7 +357,7 @@ impl VulkanDecoder<'_> { .reference_slots(&reference_slots); unsafe { - self.vulkan_ctx + self.vulkan_device .device .video_queue_ext .cmd_begin_video_coding_khr(*self.command_buffers.decode_buffer, &begin_info) @@ -354,7 +369,7 @@ impl VulkanDecoder<'_> { .flags(vk::VideoCodingControlFlagsKHR::RESET); unsafe { - self.vulkan_ctx + self.vulkan_device .device .video_queue_ext .cmd_control_video_coding_khr( @@ -418,7 +433,7 @@ impl VulkanDecoder<'_> { 0, ), }, - PicOrderCnt: decode_information.picture_info.PicOrderCnt, + PicOrderCnt: decode_information.picture_info.PicOrderCnt_for_decoding, seq_parameter_set_id: decode_information.sps_id, pic_parameter_set_id: decode_information.pps_id, frame_num: decode_information.header.frame_num, @@ -461,23 +476,23 @@ impl VulkanDecoder<'_> { .reference_slots(&pic_reference_slots) .push_next(&mut decode_h264_picture_info); - if let Some(pool) = self.decode_query_pool.as_ref() { + if let Some(pool) = video_session_resources.decode_query_pool.as_ref() { pool.begin_query(*self.command_buffers.decode_buffer); } unsafe { - self.vulkan_ctx + self.vulkan_device .device .video_decode_queue_ext .cmd_decode_video_khr(*self.command_buffers.decode_buffer, &decode_info) }; - if let Some(pool) = self.decode_query_pool.as_ref() { + if let Some(pool) = video_session_resources.decode_query_pool.as_ref() { pool.end_query(*self.command_buffers.decode_buffer); } unsafe { - self.vulkan_ctx + self.vulkan_device .device .video_queue_ext .cmd_end_video_coding_khr( @@ -488,7 +503,7 @@ impl VulkanDecoder<'_> { self.command_buffers.decode_buffer.end()?; - self.vulkan_ctx.queues.h264_decode.submit( + self.vulkan_device.queues.h264_decode.submit( &self.command_buffers.decode_buffer, &[], &[( @@ -502,23 +517,33 @@ impl VulkanDecoder<'_> { self.reference_id_to_dpb_slot_index .insert(reference_id, new_reference_slot_index); - // TODO: those are not the real dimensions of the image. the real dimensions should be - // calculated from the sps - let dimensions = video_session_resources.video_session.max_coded_extent; + let sps = video_session_resources + .sps + .get(&decode_information.sps_id) + .ok_or(VulkanDecoderError::NoSession)?; + + let dimensions = vk::Extent2D { + width: sps.width()?, + height: sps.height()?, + }; - Ok(DecodeOutput { + Ok(DecodeSubmission { image: target_image, wait_semaphore: *self.sync_structures.sem_decode_done, layer: target_layer as u32, current_layout: target_image_layout, dimensions, _input_buffer: decode_buffer, + picture_order_cnt: decode_information.picture_info.PicOrderCnt_for_decoding[0], + max_num_reorder_frames: video_session_resources.max_num_reorder_frames, + is_idr, + pts: decode_information.pts, }) } fn output_to_wgpu_texture( &self, - decode_output: DecodeOutput, + decode_output: DecodeSubmission, ) -> Result { let copy_extent = vk::Extent3D { width: decode_output.dimensions.width, @@ -527,8 +552,8 @@ impl VulkanDecoder<'_> { }; let queue_indices = [ - self.vulkan_ctx.queues.transfer.idx as u32, - self.vulkan_ctx.queues.wgpu.idx as u32, + self.vulkan_device.queues.transfer.idx as u32, + self.vulkan_device.queues.wgpu.idx as u32, ]; let create_info = vk::ImageCreateInfo::default() @@ -549,7 +574,10 @@ impl VulkanDecoder<'_> { .queue_family_indices(&queue_indices) .initial_layout(vk::ImageLayout::UNDEFINED); - let image = Arc::new(Image::new(self.vulkan_ctx.allocator.clone(), &create_info)?); + let image = Arc::new(Image::new( + self.vulkan_device.allocator.clone(), + &create_info, + )?); self.command_buffers .vulkan_to_wgpu_transfer_buffer @@ -592,7 +620,7 @@ impl VulkanDecoder<'_> { }); unsafe { - self.vulkan_ctx.device.cmd_pipeline_barrier2( + self.vulkan_device.device.cmd_pipeline_barrier2( *self.command_buffers.vulkan_to_wgpu_transfer_buffer, &vk::DependencyInfo::default() .image_memory_barriers(&[memory_barrier_src, memory_barrier_dst]), @@ -639,7 +667,7 @@ impl VulkanDecoder<'_> { ]; unsafe { - self.vulkan_ctx.device.cmd_copy_image( + self.vulkan_device.device.cmd_copy_image( *self.command_buffers.vulkan_to_wgpu_transfer_buffer, decode_output.image, vk::ImageLayout::TRANSFER_SRC_OPTIMAL, @@ -666,7 +694,7 @@ impl VulkanDecoder<'_> { .new_layout(vk::ImageLayout::GENERAL); unsafe { - self.vulkan_ctx.device.cmd_pipeline_barrier2( + self.vulkan_device.device.cmd_pipeline_barrier2( *self.command_buffers.vulkan_to_wgpu_transfer_buffer, &vk::DependencyInfo::default() .image_memory_barriers(&[memory_barrier_src, memory_barrier_dst]), @@ -675,7 +703,7 @@ impl VulkanDecoder<'_> { self.command_buffers.vulkan_to_wgpu_transfer_buffer.end()?; - self.vulkan_ctx.queues.transfer.submit( + self.vulkan_device.queues.transfer.submit( &self.command_buffers.vulkan_to_wgpu_transfer_buffer, &[( decode_output.wait_semaphore, @@ -690,8 +718,9 @@ impl VulkanDecoder<'_> { .wait_and_reset(u64::MAX)?; let result = self - .decode_query_pool + .video_session_resources .as_ref() + .and_then(|s| s.decode_query_pool.as_ref()) .map(|pool| pool.get_result_blocking()); if let Some(result) = result { @@ -726,9 +755,8 @@ impl VulkanDecoder<'_> { }; let wgpu_texture = unsafe { - self.vulkan_ctx - .wgpu_ctx - .device + self.vulkan_device + .wgpu_device .create_texture_from_hal::( hal_texture, &wgpu::TextureDescriptor { @@ -753,7 +781,10 @@ impl VulkanDecoder<'_> { Ok(wgpu_texture) } - fn download_output(&self, decode_output: DecodeOutput) -> Result, VulkanDecoderError> { + fn download_output( + &self, + decode_output: DecodeSubmission, + ) -> Result, VulkanDecoderError> { let mut dst_buffer = self.copy_image_to_buffer( decode_output.image, decode_output.dimensions, @@ -787,7 +818,7 @@ impl VulkanDecoder<'_> { .reference_list .iter() .flatten() - .map(|ref_info| ref_info.picture_info.into()) + .map(|&ref_info| ref_info.into()) .collect::>() } @@ -806,7 +837,7 @@ impl VulkanDecoder<'_> { references_dpb_slot_info: &'a mut [vk::VideoDecodeH264DpbSlotInfoKHR<'a>], decode_information: &'a DecodeInformation, ) -> Result>, VulkanDecoderError> { - let mut pic_reference_slots = Vec::new(); + let mut pic_reference_slots: Vec> = Vec::new(); for (ref_info, dpb_slot_info) in decode_information .reference_list .iter() @@ -827,7 +858,12 @@ impl VulkanDecoder<'_> { let reference = reference.push_next(dpb_slot_info); - pic_reference_slots.push(reference); + if pic_reference_slots + .iter() + .all(|r| r.slot_index != reference.slot_index) + { + pic_reference_slots.push(reference); + } } Ok(pic_reference_slots) @@ -865,18 +901,16 @@ impl VulkanDecoder<'_> { }); unsafe { - self.vulkan_ctx.device.cmd_pipeline_barrier2( + self.vulkan_device.device.cmd_pipeline_barrier2( *self.command_buffers.gpu_to_mem_transfer_buffer, &vk::DependencyInfo::default().image_memory_barriers(&[memory_barrier]), ) }; - // TODO: in this section, we shouldn't be using `max_coded_extent` and use the real frame - // resolution let y_plane_size = dimensions.width as u64 * dimensions.height as u64; let dst_buffer = Buffer::new_transfer( - self.vulkan_ctx.allocator.clone(), + self.vulkan_device.allocator.clone(), y_plane_size * 3 / 2, TransferDirection::GpuToMem, )?; @@ -917,7 +951,7 @@ impl VulkanDecoder<'_> { ]; unsafe { - self.vulkan_ctx.device.cmd_copy_image_to_buffer( + self.vulkan_device.device.cmd_copy_image_to_buffer( *self.command_buffers.gpu_to_mem_transfer_buffer, image, vk::ImageLayout::TRANSFER_SRC_OPTIMAL, @@ -935,7 +969,7 @@ impl VulkanDecoder<'_> { .new_layout(current_image_layout); unsafe { - self.vulkan_ctx.device.cmd_pipeline_barrier2( + self.vulkan_device.device.cmd_pipeline_barrier2( *self.command_buffers.gpu_to_mem_transfer_buffer, &vk::DependencyInfo::default().image_memory_barriers(&[memory_barrier]), ) @@ -943,7 +977,7 @@ impl VulkanDecoder<'_> { self.command_buffers.gpu_to_mem_transfer_buffer.end()?; - self.vulkan_ctx.queues.transfer.submit( + self.vulkan_device.queues.transfer.submit( &self.command_buffers.gpu_to_mem_transfer_buffer, wait_semaphores, signal_semaphores, @@ -953,41 +987,3 @@ impl VulkanDecoder<'_> { Ok(dst_buffer) } } - -pub(crate) struct H264ProfileInfo<'a> { - profile_info: vk::VideoProfileInfoKHR<'a>, - h264_info_ptr: *mut vk::VideoDecodeH264ProfileInfoKHR<'a>, -} - -impl H264ProfileInfo<'_> { - fn decode_h264_yuv420() -> Self { - let h264_profile_info = Box::leak(Box::new( - vk::VideoDecodeH264ProfileInfoKHR::default() - .std_profile_idc( - vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_BASELINE, - ) - .picture_layout(vk::VideoDecodeH264PictureLayoutFlagsKHR::PROGRESSIVE), - )); - - let h264_info_ptr = h264_profile_info as *mut _; - let profile_info = vk::VideoProfileInfoKHR::default() - .video_codec_operation(vk::VideoCodecOperationFlagsKHR::DECODE_H264) - .chroma_subsampling(vk::VideoChromaSubsamplingFlagsKHR::TYPE_420) - .luma_bit_depth(vk::VideoComponentBitDepthFlagsKHR::TYPE_8) - .chroma_bit_depth(vk::VideoComponentBitDepthFlagsKHR::TYPE_8) - .push_next(h264_profile_info); - - Self { - profile_info, - h264_info_ptr, - } - } -} - -impl<'a> Drop for H264ProfileInfo<'a> { - fn drop(&mut self) { - unsafe { - let _ = Box::from_raw(self.h264_info_ptr); - } - } -} diff --git a/vk-video/src/vulkan_decoder/frame_sorter.rs b/vk-video/src/vulkan_decoder/frame_sorter.rs new file mode 100644 index 000000000..78d38da6b --- /dev/null +++ b/vk-video/src/vulkan_decoder/frame_sorter.rs @@ -0,0 +1,69 @@ +use std::collections::BinaryHeap; + +use crate::Frame; + +use super::DecodeResult; + +impl PartialEq for DecodeResult { + fn eq(&self, other: &Self) -> bool { + self.pic_order_cnt.eq(&other.pic_order_cnt) + } +} + +impl Eq for DecodeResult {} + +impl PartialOrd for DecodeResult { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } +} + +impl Ord for DecodeResult { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.pic_order_cnt.cmp(&other.pic_order_cnt).reverse() + } +} + +pub(crate) struct FrameSorter { + frames: BinaryHeap>, +} + +impl FrameSorter { + pub(crate) fn new() -> Self { + Self { + frames: BinaryHeap::new(), + } + } + + pub(crate) fn put(&mut self, frame: DecodeResult) -> Vec> { + let max_num_reorder_frames = frame.max_num_reorder_frames as usize; + let is_idr = frame.is_idr; + let mut result = Vec::new(); + + if is_idr { + while !self.frames.is_empty() { + let frame = self.frames.pop().unwrap(); + + result.push(Frame { + frame: frame.frame, + pts: frame.pts, + }); + } + + self.frames.push(frame); + } else { + self.frames.push(frame); + + while self.frames.len() > max_num_reorder_frames { + let frame = self.frames.pop().unwrap(); + + result.push(Frame { + frame: frame.frame, + pts: frame.pts, + }); + } + } + + result + } +} diff --git a/vk-video/src/vulkan_decoder/session_resources.rs b/vk-video/src/vulkan_decoder/session_resources.rs index e59c71e09..9c41a1fb1 100644 --- a/vk-video/src/vulkan_decoder/session_resources.rs +++ b/vk-video/src/vulkan_decoder/session_resources.rs @@ -1,42 +1,87 @@ +use std::collections::HashMap; + use ash::vk; -use h264_reader::nal::{pps::PicParameterSet, sps::SeqParameterSet}; +use h264_reader::nal::{ + pps::PicParameterSet, + sps::{Profile, SeqParameterSet}, +}; use images::DecodingImages; use parameters::VideoSessionParametersManager; use super::{ - CommandBuffer, Fence, H264ProfileInfo, SeqParameterSetExt, VideoSession, VulkanCtx, - VulkanDecoderError, + h264_level_idc_to_max_dpb_mbs, vk_to_h264_level_idc, CommandBuffer, DecodeQueryPool, Fence, + H264ProfileInfo, SeqParameterSetExt, VideoSession, VulkanDecoderError, VulkanDevice, }; mod images; mod parameters; pub(super) struct VideoSessionResources<'a> { + pub(crate) profile_info: H264ProfileInfo<'a>, pub(crate) video_session: VideoSession, pub(crate) parameters_manager: VideoSessionParametersManager, pub(crate) decoding_images: DecodingImages<'a>, + pub(crate) sps: HashMap, + pub(crate) pps: HashMap<(u8, u8), PicParameterSet>, + pub(crate) decode_query_pool: Option, + pub(crate) level_idc: u8, + pub(crate) max_num_reorder_frames: u64, +} + +fn calculate_max_num_reorder_frames(sps: &SeqParameterSet) -> Result { + let fallback_max_num_reorder_frames = if [44u8, 86, 100, 110, 122, 244] + .contains(&sps.profile_idc.into()) + && sps.constraint_flags.flag3() + { + 0 + } else if let Profile::Baseline = sps.profile() { + 0 + } else { + h264_level_idc_to_max_dpb_mbs(sps.level_idc)? + / ((sps.pic_width_in_mbs_minus1 as u64 + 1) + * (sps.pic_height_in_map_units_minus1 as u64 + 1)) + .min(16) + }; + + let max_num_reorder_frames = sps + .vui_parameters + .as_ref() + .and_then(|v| v.bitstream_restrictions.as_ref()) + .map(|b| b.max_num_reorder_frames as u64) + .unwrap_or(fallback_max_num_reorder_frames); + + Ok(max_num_reorder_frames) } impl VideoSessionResources<'_> { pub(crate) fn new_from_sps( - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, decode_buffer: &CommandBuffer, - sps: &SeqParameterSet, + sps: SeqParameterSet, fence_memory_barrier_completed: &Fence, ) -> Result { - let profile = H264ProfileInfo::decode_h264_yuv420(); + let profile_info = H264ProfileInfo::from_sps_decode(&sps)?; + + let level_idc = sps.level_idc; + let max_level_idc = vk_to_h264_level_idc(vulkan_ctx.h264_caps.max_level_idc)?; + + if level_idc > max_level_idc { + return Err(VulkanDecoderError::InvalidInputData( + format!("stream has level_idc = {level_idc}, while the GPU can decode at most {max_level_idc}") + )); + } let width = sps.width()?; let height = sps.height()?; - let max_coded_extent = vk::Extent2D { width, height }; // +1 for current frame let max_dpb_slots = sps.max_num_ref_frames + 1; let max_active_references = sps.max_num_ref_frames; + let max_num_reorder_frames = calculate_max_num_reorder_frames(&sps)?; let video_session = VideoSession::new( vulkan_ctx, - &profile.profile_info, + &profile_info.profile_info, max_coded_extent, max_dpb_slots, max_active_references, @@ -46,31 +91,60 @@ impl VideoSessionResources<'_> { let mut parameters_manager = VideoSessionParametersManager::new(vulkan_ctx, video_session.session)?; - parameters_manager.put_sps(sps)?; + parameters_manager.put_sps(&sps)?; let decoding_images = Self::new_decoding_images( vulkan_ctx, + &profile_info, max_coded_extent, max_dpb_slots, decode_buffer, fence_memory_barrier_completed, )?; + let sps = HashMap::from_iter([(sps.id().id(), sps)]); + let decode_query_pool = if vulkan_ctx + .queues + .h264_decode + .supports_result_status_queries() + { + Some(DecodeQueryPool::new( + vulkan_ctx.device.clone(), + profile_info.profile_info, + )?) + } else { + None + }; + Ok(VideoSessionResources { + profile_info, video_session, parameters_manager, decoding_images, + sps, + pps: HashMap::new(), + decode_query_pool, + level_idc, + max_num_reorder_frames, }) } pub(crate) fn process_sps( &mut self, - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, decode_buffer: &CommandBuffer, - sps: &SeqParameterSet, + sps: SeqParameterSet, fence_memory_barrier_completed: &Fence, ) -> Result<(), VulkanDecoderError> { - let profile = H264ProfileInfo::decode_h264_yuv420(); + let new_profile = H264ProfileInfo::from_sps_decode(&sps)?; + + if self.profile_info != new_profile { + return Err(VulkanDecoderError::ProfileChangeUnsupported); + } + + if self.level_idc != sps.level_idc { + return Err(VulkanDecoderError::LevelChangeUnsupported); + } let width = sps.width()?; let height = sps.height()?; @@ -85,13 +159,13 @@ impl VideoSessionResources<'_> { && self.video_session.max_dpb_slots >= max_dpb_slots { // no need to change the session - self.parameters_manager.put_sps(sps)?; + self.parameters_manager.put_sps(&sps)?; return Ok(()); } self.video_session = VideoSession::new( vulkan_ctx, - &profile.profile_info, + &self.profile_info.profile_info, max_coded_extent, max_dpb_slots, max_active_references, @@ -100,32 +174,39 @@ impl VideoSessionResources<'_> { self.parameters_manager .change_session(self.video_session.session)?; - self.parameters_manager.put_sps(sps)?; + self.parameters_manager.put_sps(&sps)?; self.decoding_images = Self::new_decoding_images( vulkan_ctx, + &self.profile_info, max_coded_extent, max_dpb_slots, decode_buffer, fence_memory_barrier_completed, )?; + self.sps.insert(sps.id().id(), sps); + Ok(()) } - pub(crate) fn process_pps(&mut self, pps: &PicParameterSet) -> Result<(), VulkanDecoderError> { - self.parameters_manager.put_pps(pps) + pub(crate) fn process_pps(&mut self, pps: PicParameterSet) -> Result<(), VulkanDecoderError> { + self.parameters_manager.put_pps(&pps)?; + self.pps.insert( + (pps.seq_parameter_set_id.id(), pps.pic_parameter_set_id.id()), + pps, + ); + Ok(()) } fn new_decoding_images<'a>( - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, + profile: &H264ProfileInfo, max_coded_extent: vk::Extent2D, max_dpb_slots: u32, decode_buffer: &CommandBuffer, fence_memory_barrier_completed: &Fence, ) -> Result, VulkanDecoderError> { - let profile = H264ProfileInfo::decode_h264_yuv420(); - // FIXME: usually, sps arrives either at the start of the stream (when all spses are sent // at the begginning of the stream) or right before an IDR. It is however possible for an // sps nal to arrive in between P-frames. This would cause us to loose the reference diff --git a/vk-video/src/vulkan_decoder/session_resources/images.rs b/vk-video/src/vulkan_decoder/session_resources/images.rs index c62afbd50..ab88132fc 100644 --- a/vk-video/src/vulkan_decoder/session_resources/images.rs +++ b/vk-video/src/vulkan_decoder/session_resources/images.rs @@ -4,7 +4,7 @@ use ash::vk; use crate::{ vulkan_decoder::{H264ProfileInfo, Image, ImageView}, - VulkanCtx, VulkanDecoderError, + VulkanDecoderError, VulkanDevice, }; pub(crate) struct DecodingImages<'a> { @@ -22,7 +22,7 @@ pub(crate) struct DecodingImageBundle<'a> { impl<'a> DecodingImageBundle<'a> { #[allow(clippy::too_many_arguments)] pub(crate) fn new( - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, format: &vk::VideoFormatPropertiesKHR<'a>, dimensions: vk::Extent2D, image_usage: vk::ImageUsageFlags, @@ -156,8 +156,8 @@ impl<'a> DecodingImages<'a> { } pub(crate) fn new( - vulkan_ctx: &VulkanCtx, - profile: H264ProfileInfo, + vulkan_ctx: &VulkanDevice, + profile: &H264ProfileInfo, dpb_format: &vk::VideoFormatPropertiesKHR<'a>, dst_format: &Option>, dimensions: vk::Extent2D, @@ -182,7 +182,7 @@ impl<'a> DecodingImages<'a> { dpb_format, dimensions, dpb_image_usage, - &profile, + profile, max_dpb_slots, if dst_format.is_some() { None @@ -202,7 +202,7 @@ impl<'a> DecodingImages<'a> { &dst_format, dimensions, dst_image_usage, - &profile, + profile, 1, Some(&queue_indices), vk::ImageLayout::VIDEO_DECODE_DST_KHR, diff --git a/vk-video/src/vulkan_decoder/session_resources/parameters.rs b/vk-video/src/vulkan_decoder/session_resources/parameters.rs index e5f366f67..97af83f06 100644 --- a/vk-video/src/vulkan_decoder/session_resources/parameters.rs +++ b/vk-video/src/vulkan_decoder/session_resources/parameters.rs @@ -7,7 +7,7 @@ use crate::{ vulkan_decoder::{ Device, VideoSessionParameters, VkPictureParameterSet, VkSequenceParameterSet, }, - VulkanCtx, VulkanDecoderError, + VulkanDecoderError, VulkanDevice, }; /// Since `VideoSessionParameters` can only add sps and pps values (inserting sps or pps with an @@ -23,7 +23,7 @@ pub(crate) struct VideoSessionParametersManager { impl VideoSessionParametersManager { pub(crate) fn new( - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, session: vk::VideoSessionKHR, ) -> Result { Ok(Self { diff --git a/vk-video/src/vulkan_decoder/vulkan_ctx.rs b/vk-video/src/vulkan_decoder/vulkan_ctx.rs index befb3c19b..daf9761e2 100644 --- a/vk-video/src/vulkan_decoder/vulkan_ctx.rs +++ b/vk-video/src/vulkan_decoder/vulkan_ctx.rs @@ -4,11 +4,14 @@ use std::{ }; use ash::{vk, Entry}; -use tracing::{error, info}; +use tracing::{debug, error, warn}; +use wgpu::hal::Adapter; + +use crate::{parser::Parser, BytesDecoder, DecoderError, WgpuTexturesDeocder}; use super::{ - Allocator, CommandBuffer, CommandPool, DebugMessenger, Device, H264ProfileInfo, Instance, - VulkanDecoderError, + Allocator, CommandBuffer, CommandPool, DebugMessenger, Device, FrameSorter, Instance, + VulkanDecoder, VulkanDecoderError, }; const REQUIRED_EXTENSIONS: &[&CStr] = &[ @@ -44,111 +47,17 @@ pub enum VulkanCtxError { StringConversionError(#[from] std::ffi::FromBytesUntilNulError), } -pub struct VulkanCtx { +pub struct VulkanInstance { _entry: Arc, - _instance: Arc, - _physical_device: vk::PhysicalDevice, - pub(crate) device: Arc, - pub(crate) allocator: Arc, - pub(crate) queues: Queues, + instance: Arc, _debug_messenger: Option, - pub(crate) video_capabilities: vk::VideoCapabilitiesKHR<'static>, - pub(crate) h264_dpb_format_properties: vk::VideoFormatPropertiesKHR<'static>, - pub(crate) h264_dst_format_properties: Option>, - pub wgpu_ctx: WgpuCtx, -} - -pub struct WgpuCtx { - pub instance: Arc, - pub adapter: Arc, - pub device: Arc, - pub queue: Arc, -} - -pub(crate) struct CommandPools { - pub(crate) _decode_pool: Arc, - pub(crate) _transfer_pool: Arc, -} - -pub(crate) struct Queue { - pub(crate) queue: std::sync::Mutex, - pub(crate) idx: usize, - _video_properties: vk::QueueFamilyVideoPropertiesKHR<'static>, - pub(crate) query_result_status_properties: - vk::QueueFamilyQueryResultStatusPropertiesKHR<'static>, - device: Arc, -} - -impl Queue { - pub(crate) fn supports_result_status_queries(&self) -> bool { - self.query_result_status_properties - .query_result_status_support - == vk::TRUE - } - - pub(crate) fn submit( - &self, - buffer: &CommandBuffer, - wait_semaphores: &[(vk::Semaphore, vk::PipelineStageFlags2)], - signal_semaphores: &[(vk::Semaphore, vk::PipelineStageFlags2)], - fence: Option, - ) -> Result<(), VulkanDecoderError> { - fn to_sem_submit_info( - submits: &[(vk::Semaphore, vk::PipelineStageFlags2)], - ) -> Vec { - submits - .iter() - .map(|&(sem, stage)| { - vk::SemaphoreSubmitInfo::default() - .semaphore(sem) - .stage_mask(stage) - }) - .collect::>() - } - - let wait_semaphores = to_sem_submit_info(wait_semaphores); - let signal_semaphores = to_sem_submit_info(signal_semaphores); - - let buffer_submit_info = - [vk::CommandBufferSubmitInfo::default().command_buffer(buffer.buffer)]; - - let submit_info = [vk::SubmitInfo2::default() - .wait_semaphore_infos(&wait_semaphores) - .signal_semaphore_infos(&signal_semaphores) - .command_buffer_infos(&buffer_submit_info)]; - - unsafe { - self.device.queue_submit2( - *self.queue.lock().unwrap(), - &submit_info, - fence.unwrap_or(vk::Fence::null()), - )? - }; - - Ok(()) - } -} - -pub(crate) struct Queues { - pub(crate) transfer: Queue, - pub(crate) h264_decode: Queue, - pub(crate) wgpu: Queue, + pub wgpu_instance: Arc, } -impl VulkanCtx { - pub fn new( - wgpu_features: wgpu::Features, - wgpu_limits: wgpu::Limits, - ) -> Result { +impl VulkanInstance { + pub fn new() -> Result, VulkanCtxError> { let entry = Arc::new(unsafe { Entry::load()? }); - let instance_extension_properties = - unsafe { entry.enumerate_instance_extension_properties(None)? }; - info!( - "instance_extension_properties amount: {}", - instance_extension_properties.len() - ); - let api_version = vk::make_api_version(0, 1, 3, 0); let app_info = vk::ApplicationInfo { api_version, @@ -232,25 +141,47 @@ impl VulkanCtx { )? }; - let physical_devices = unsafe { instance.enumerate_physical_devices()? }; + let wgpu_instance = + unsafe { wgpu::Instance::from_hal::(wgpu_instance) }; + + Ok(Self { + _entry: entry, + instance, + _debug_messenger: debug_messenger, + wgpu_instance: wgpu_instance.into(), + } + .into()) + } + + /// The `compatible surface` being a `&mut Option<&mut wgpu::Surface<'_>>` is a result of + /// weirdness in wgpu API, which we fixed upstream. When wgpu releases, this will be converted to + /// `Option<&wgpu::Surface<'_>>` + pub fn create_device( + &self, + wgpu_features: wgpu::Features, + wgpu_limits: wgpu::Limits, + compatible_surface: &mut Option<&mut wgpu::Surface<'_>>, + ) -> Result, VulkanCtxError> { + let physical_devices = unsafe { self.instance.enumerate_physical_devices()? }; let ChosenDevice { physical_device, + wgpu_adapter, queue_indices, h264_dpb_format_properties, h264_dst_format_properties, video_capabilities, - } = find_device(&physical_devices, &instance, REQUIRED_EXTENSIONS)?; - - let wgpu_adapter = wgpu_instance - .expose_adapter(physical_device) - .ok_or(VulkanCtxError::WgpuAdapterNotCreated)?; + h264_caps, + } = find_device( + &physical_devices, + &self.instance, + &self.wgpu_instance, + REQUIRED_EXTENSIONS, + compatible_surface, + )?; let wgpu_features = wgpu_features | wgpu::Features::TEXTURE_FORMAT_NV12; - // TODO: we can only get the required extensions after exposing the adapter; the creation - // of the adapter and verification of whether the device supports all extensions should - // happen while picking the device. let wgpu_extensions = wgpu_adapter .adapter .required_device_extensions(wgpu_features); @@ -283,15 +214,19 @@ impl VulkanCtx { .add_to_device_create(device_create_info) .push_next(&mut vk_synch_2_feature); - let device = unsafe { instance.create_device(physical_device, &device_create_info, None)? }; - let video_queue_ext = ash::khr::video_queue::Device::new(&instance, &device); - let video_decode_queue_ext = ash::khr::video_decode_queue::Device::new(&instance, &device); + let device = unsafe { + self.instance + .create_device(physical_device, &device_create_info, None)? + }; + let video_queue_ext = ash::khr::video_queue::Device::new(&self.instance, &device); + let video_decode_queue_ext = + ash::khr::video_decode_queue::Device::new(&self.instance, &device); let device = Arc::new(Device { device, video_queue_ext, video_decode_queue_ext, - _instance: instance.clone(), + _instance: self.instance.clone(), }); let h264_decode_queue = @@ -345,14 +280,12 @@ impl VulkanCtx { }; let allocator = Arc::new(Allocator::new( - instance.clone(), + self.instance.clone(), physical_device, device.clone(), )?); - let wgpu_instance = - unsafe { wgpu::Instance::from_hal::(wgpu_instance) }; - let wgpu_adapter = unsafe { wgpu_instance.create_adapter_from_hal(wgpu_adapter) }; + let wgpu_adapter = unsafe { self.wgpu_instance.create_adapter_from_hal(wgpu_adapter) }; let (wgpu_device, wgpu_queue) = unsafe { wgpu_adapter.create_device_from_hal( wgpu_device, @@ -366,51 +299,115 @@ impl VulkanCtx { )? }; - let wgpu_ctx = WgpuCtx { - instance: Arc::new(wgpu_instance), - adapter: Arc::new(wgpu_adapter), - device: Arc::new(wgpu_device), - queue: Arc::new(wgpu_queue), - }; - - Ok(Self { - _entry: entry, - _instance: instance, + Ok(VulkanDevice { _physical_device: physical_device, device, allocator, queues, - _debug_messenger: debug_messenger, video_capabilities, h264_dpb_format_properties, h264_dst_format_properties, - wgpu_ctx, + h264_caps, + wgpu_device: wgpu_device.into(), + wgpu_queue: wgpu_queue.into(), + wgpu_adapter: wgpu_adapter.into(), + } + .into()) + } +} + +impl std::fmt::Debug for VulkanInstance { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("VulkanInstance").finish() + } +} + +pub struct VulkanDevice { + _physical_device: vk::PhysicalDevice, + pub(crate) device: Arc, + pub(crate) allocator: Arc, + pub(crate) queues: Queues, + pub(crate) video_capabilities: vk::VideoCapabilitiesKHR<'static>, + pub(crate) h264_dpb_format_properties: vk::VideoFormatPropertiesKHR<'static>, + pub(crate) h264_dst_format_properties: Option>, + pub(crate) h264_caps: vk::VideoDecodeH264CapabilitiesKHR<'static>, + pub wgpu_device: Arc, + pub wgpu_queue: Arc, + pub wgpu_adapter: Arc, +} + +impl VulkanDevice { + pub fn create_wgpu_textures_decoder( + self: &Arc, + ) -> Result { + let parser = Parser::default(); + let vulkan_decoder = VulkanDecoder::new(self.clone())?; + let frame_sorter = FrameSorter::::new(); + + Ok(WgpuTexturesDeocder { + parser, + vulkan_decoder, + frame_sorter, + }) + } + + pub fn create_bytes_decoder(self: &Arc) -> Result { + let parser = Parser::default(); + let vulkan_decoder = VulkanDecoder::new(self.clone())?; + let frame_sorter = FrameSorter::>::new(); + + Ok(BytesDecoder { + parser, + vulkan_decoder, + frame_sorter, }) } } -impl std::fmt::Debug for VulkanCtx { +impl std::fmt::Debug for VulkanDevice { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - f.debug_struct("VulkanCtx").finish() + f.debug_struct("VulkanDevice").finish() } } struct ChosenDevice<'a> { physical_device: vk::PhysicalDevice, + wgpu_adapter: wgpu::hal::ExposedAdapter, queue_indices: QueueIndices<'a>, h264_dpb_format_properties: vk::VideoFormatPropertiesKHR<'a>, h264_dst_format_properties: Option>, video_capabilities: vk::VideoCapabilitiesKHR<'a>, + h264_caps: vk::VideoDecodeH264CapabilitiesKHR<'a>, } fn find_device<'a>( devices: &[vk::PhysicalDevice], instance: &Instance, + wgpu_instance: &wgpu::Instance, required_extension_names: &[&CStr], + compatible_surface: &mut Option<&mut wgpu::Surface<'_>>, ) -> Result, VulkanCtxError> { for &device in devices { let properties = unsafe { instance.get_physical_device_properties(device) }; + let wgpu_instance = unsafe { wgpu_instance.as_hal::() }.unwrap(); + + let wgpu_adapter = wgpu_instance + .expose_adapter(device) + .ok_or(VulkanCtxError::WgpuAdapterNotCreated)?; + + if let Some(surface) = compatible_surface { + let surface_capabilities = unsafe { + (*surface).as_hal::(|surface| { + surface.and_then(|surface| wgpu_adapter.adapter.surface_capabilities(surface)) + }) + }; + + if surface_capabilities.is_none() { + continue; + } + } + let mut vk_13_features = vk::PhysicalDeviceVulkan13Features::default(); let mut features = vk::PhysicalDeviceFeatures2::default().push_next(&mut vk_13_features); @@ -418,7 +415,7 @@ fn find_device<'a>( let extensions = unsafe { instance.enumerate_device_extension_properties(device)? }; if vk_13_features.synchronization2 == 0 { - error!( + warn!( "device {:?} does not support the required synchronization2 feature", properties.device_name_as_c_str()? ); @@ -437,7 +434,7 @@ fn find_device<'a>( true }) }) { - error!( + warn!( "device {:?} does not support the required extensions", properties.device_name_as_c_str()? ); @@ -463,7 +460,16 @@ fn find_device<'a>( unsafe { instance.get_physical_device_queue_family_properties2(device, &mut queues) }; - let profile_info = H264ProfileInfo::decode_h264_yuv420(); + let mut h264_profile_info = vk::VideoDecodeH264ProfileInfoKHR::default() + .picture_layout(vk::VideoDecodeH264PictureLayoutFlagsKHR::PROGRESSIVE) + .std_profile_idc(vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_HIGH); + + let profile_info = vk::VideoProfileInfoKHR::default() + .video_codec_operation(vk::VideoCodecOperationFlagsKHR::DECODE_H264) + .chroma_subsampling(vk::VideoChromaSubsamplingFlagsKHR::TYPE_420) + .luma_bit_depth(vk::VideoComponentBitDepthFlagsKHR::TYPE_8) + .chroma_bit_depth(vk::VideoComponentBitDepthFlagsKHR::TYPE_8) + .push_next(&mut h264_profile_info); let mut h264_caps = vk::VideoDecodeH264CapabilitiesKHR::default(); let mut decode_caps = vk::VideoDecodeCapabilitiesKHR { @@ -478,9 +484,7 @@ fn find_device<'a>( .video_queue_instance_ext .fp() .get_physical_device_video_capabilities_khr)( - device, - &profile_info.profile_info, - &mut caps, + device, &profile_info, &mut caps ) .result()? }; @@ -495,7 +499,11 @@ fn find_device<'a>( .max_dpb_slots(caps.max_dpb_slots) .max_active_reference_pictures(caps.max_active_reference_pictures) .std_header_version(caps.std_header_version); - info!("caps: {caps:#?}"); + + let h264_caps = vk::VideoDecodeH264CapabilitiesKHR::default() + .max_level_idc(h264_caps.max_level_idc) + .field_offset_granularity(h264_caps.field_offset_granularity); + debug!("video_caps: {caps:#?}"); let flags = decode_caps.flags; @@ -563,7 +571,7 @@ fn find_device<'a>( .contains(vk::QueueFlags::VIDEO_DECODE_KHR) }) .map(|(i, _)| i) - .collect::>(); // TODO: have to split the queues + .collect::>(); let Some(transfer_queue_idx) = queues .iter() @@ -603,13 +611,14 @@ fn find_device<'a>( continue; }; - info!("deocde_caps: {decode_caps:#?}"); - info!("h264_caps: {h264_caps:#?}"); - info!("dpb_format_properties: {h264_dpb_format_properties:#?}"); - info!("dst_format_properties: {h264_dst_format_properties:#?}"); + debug!("deocde_caps: {decode_caps:#?}"); + debug!("h264_caps: {h264_caps:#?}"); + debug!("dpb_format_properties: {h264_dpb_format_properties:#?}"); + debug!("dst_format_properties: {h264_dst_format_properties:#?}"); return Ok(ChosenDevice { physical_device: device, + wgpu_adapter, queue_indices: QueueIndices { transfer: QueueIndex { idx: transfer_queue_idx, @@ -633,6 +642,7 @@ fn find_device<'a>( h264_dpb_format_properties, h264_dst_format_properties, video_capabilities, + h264_caps, }); } @@ -642,11 +652,11 @@ fn find_device<'a>( fn query_video_format_properties<'a>( device: vk::PhysicalDevice, video_queue_instance_ext: &ash::khr::video_queue::Instance, - profile_info: &H264ProfileInfo, + profile_info: &vk::VideoProfileInfoKHR<'_>, image_usage: vk::ImageUsageFlags, ) -> Result>, VulkanCtxError> { - let mut profile_list_info = vk::VideoProfileListInfoKHR::default() - .profiles(std::slice::from_ref(&profile_info.profile_info)); + let mut profile_list_info = + vk::VideoProfileListInfoKHR::default().profiles(std::slice::from_ref(profile_info)); let format_info = vk::PhysicalDeviceVideoFormatInfoKHR::default() .image_usage(image_usage) @@ -684,6 +694,76 @@ fn query_video_format_properties<'a>( Ok(format_properties) } +pub(crate) struct CommandPools { + pub(crate) _decode_pool: Arc, + pub(crate) _transfer_pool: Arc, +} + +pub(crate) struct Queue { + pub(crate) queue: std::sync::Mutex, + pub(crate) idx: usize, + _video_properties: vk::QueueFamilyVideoPropertiesKHR<'static>, + pub(crate) query_result_status_properties: + vk::QueueFamilyQueryResultStatusPropertiesKHR<'static>, + device: Arc, +} + +impl Queue { + pub(crate) fn supports_result_status_queries(&self) -> bool { + self.query_result_status_properties + .query_result_status_support + == vk::TRUE + } + + pub(crate) fn submit( + &self, + buffer: &CommandBuffer, + wait_semaphores: &[(vk::Semaphore, vk::PipelineStageFlags2)], + signal_semaphores: &[(vk::Semaphore, vk::PipelineStageFlags2)], + fence: Option, + ) -> Result<(), VulkanDecoderError> { + fn to_sem_submit_info( + submits: &[(vk::Semaphore, vk::PipelineStageFlags2)], + ) -> Vec { + submits + .iter() + .map(|&(sem, stage)| { + vk::SemaphoreSubmitInfo::default() + .semaphore(sem) + .stage_mask(stage) + }) + .collect::>() + } + + let wait_semaphores = to_sem_submit_info(wait_semaphores); + let signal_semaphores = to_sem_submit_info(signal_semaphores); + + let buffer_submit_info = + [vk::CommandBufferSubmitInfo::default().command_buffer(buffer.buffer)]; + + let submit_info = [vk::SubmitInfo2::default() + .wait_semaphore_infos(&wait_semaphores) + .signal_semaphore_infos(&signal_semaphores) + .command_buffer_infos(&buffer_submit_info)]; + + unsafe { + self.device.queue_submit2( + *self.queue.lock().unwrap(), + &submit_info, + fence.unwrap_or(vk::Fence::null()), + )? + }; + + Ok(()) + } +} + +pub(crate) struct Queues { + pub(crate) transfer: Queue, + pub(crate) h264_decode: Queue, + pub(crate) wgpu: Queue, +} + struct QueueIndex<'a> { idx: usize, video_properties: vk::QueueFamilyVideoPropertiesKHR<'a>, diff --git a/vk-video/src/vulkan_decoder/wrappers/mem.rs b/vk-video/src/vulkan_decoder/wrappers/mem.rs index 5876702ec..2a651922a 100644 --- a/vk-video/src/vulkan_decoder/wrappers/mem.rs +++ b/vk-video/src/vulkan_decoder/wrappers/mem.rs @@ -179,12 +179,9 @@ impl Buffer { allocator: Arc, data: &[u8], buffer_size: u64, + profile_info: &H264ProfileInfo, ) -> Result { - let mut decode_buffer = Buffer::new_decode( - allocator.clone(), - buffer_size, - &H264ProfileInfo::decode_h264_yuv420(), - )?; + let mut decode_buffer = Buffer::new_decode(allocator.clone(), buffer_size, profile_info)?; unsafe { let mem = allocator.map_memory(&mut decode_buffer.allocation)?; diff --git a/vk-video/src/vulkan_decoder/wrappers/parameter_sets.rs b/vk-video/src/vulkan_decoder/wrappers/parameter_sets.rs index 2229662e3..8098583b5 100644 --- a/vk-video/src/vulkan_decoder/wrappers/parameter_sets.rs +++ b/vk-video/src/vulkan_decoder/wrappers/parameter_sets.rs @@ -197,6 +197,64 @@ impl ChromaFormatExt for h264_reader::nal::sps::ChromaFormat { } } +pub(crate) fn vk_to_h264_level_idc( + level_idc: vk::native::StdVideoH264LevelIdc, +) -> Result { + match level_idc { + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_1_0 => Ok(10), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_1_1 => Ok(11), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_1_2 => Ok(12), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_1_3 => Ok(13), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_2_0 => Ok(20), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_2_1 => Ok(21), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_2_2 => Ok(22), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_3_0 => Ok(30), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_3_1 => Ok(31), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_3_2 => Ok(32), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_4_0 => Ok(40), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_4_1 => Ok(41), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_4_2 => Ok(42), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_5_0 => Ok(50), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_5_1 => Ok(51), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_5_2 => Ok(52), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_6_0 => Ok(60), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_6_1 => Ok(61), + vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_6_2 => Ok(62), + _ => Err(VulkanDecoderError::InvalidInputData(format!( + "unknown StdVideoH264LevelIdc: {level_idc}" + ))), + } +} + +/// As per __Table A-1 Level limits__ in the H.264 spec +/// `mbs` means macroblocks here +pub(crate) fn h264_level_idc_to_max_dpb_mbs(level_idc: u8) -> Result { + match level_idc { + 10 => Ok(396), + 11 => Ok(900), + 12 => Ok(2_376), + 13 => Ok(2_376), + 20 => Ok(2_376), + 21 => Ok(4_752), + 22 => Ok(8_100), + 30 => Ok(8_100), + 31 => Ok(18_000), + 32 => Ok(20_480), + 40 => Ok(32_768), + 41 => Ok(32_768), + 42 => Ok(34_816), + 50 => Ok(110_400), + 51 => Ok(184_320), + 52 => Ok(184_320), + 60 => Ok(696_320), + 61 => Ok(696_320), + 62 => Ok(696_320), + _ => Err(VulkanDecoderError::InvalidInputData(format!( + "unknown h264 level_idc: {level_idc}" + ))), + } +} + fn h264_level_idc_to_vk(level_idc: u8) -> u32 { match level_idc { 10 => vk::native::StdVideoH264LevelIdc_STD_VIDEO_H264_LEVEL_IDC_1_0, @@ -222,6 +280,129 @@ fn h264_level_idc_to_vk(level_idc: u8) -> u32 { } } +fn h264_profile_idc_to_vk( + profile: h264_reader::nal::sps::Profile, +) -> vk::native::StdVideoH264ProfileIdc { + match profile { + h264_reader::nal::sps::Profile::Baseline => { + vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_BASELINE + } + h264_reader::nal::sps::Profile::Main => { + vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_MAIN + } + h264_reader::nal::sps::Profile::High => { + vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_HIGH + } + h264_reader::nal::sps::Profile::High444 => { + vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_HIGH_444_PREDICTIVE + } + h264_reader::nal::sps::Profile::High422 + | h264_reader::nal::sps::Profile::High10 + | h264_reader::nal::sps::Profile::Extended + | h264_reader::nal::sps::Profile::ScalableBase + | h264_reader::nal::sps::Profile::ScalableHigh + | h264_reader::nal::sps::Profile::MultiviewHigh + | h264_reader::nal::sps::Profile::StereoHigh + | h264_reader::nal::sps::Profile::MFCDepthHigh + | h264_reader::nal::sps::Profile::MultiviewDepthHigh + | h264_reader::nal::sps::Profile::EnhancedMultiviewDepthHigh + | h264_reader::nal::sps::Profile::Unknown(_) => { + vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_INVALID + } + } +} + +pub(crate) struct H264ProfileInfo<'a> { + pub(crate) profile_info: vk::VideoProfileInfoKHR<'a>, + h264_info_ptr: *mut vk::VideoDecodeH264ProfileInfoKHR<'a>, +} + +impl PartialEq for H264ProfileInfo<'_> { + fn eq(&self, other: &Self) -> bool { + unsafe { + other.profile_info.chroma_subsampling == self.profile_info.chroma_subsampling + && other.profile_info.luma_bit_depth == self.profile_info.luma_bit_depth + && other.profile_info.chroma_bit_depth == self.profile_info.chroma_bit_depth + && (*other.h264_info_ptr).std_profile_idc == (*self.h264_info_ptr).std_profile_idc + && (*other.h264_info_ptr).picture_layout == (*self.h264_info_ptr).picture_layout + } + } +} + +impl Eq for H264ProfileInfo<'_> {} + +impl H264ProfileInfo<'_> { + pub(crate) fn from_sps_decode(sps: &SeqParameterSet) -> Result { + let profile_idc = h264_profile_idc_to_vk(sps.profile()); + + if profile_idc == vk::native::StdVideoH264ProfileIdc_STD_VIDEO_H264_PROFILE_IDC_INVALID { + return Err(VulkanDecoderError::InvalidInputData( + "unsupported h264 profile".into(), + )); + } + + let h264_profile_info = Box::leak(Box::new( + vk::VideoDecodeH264ProfileInfoKHR::default() + .std_profile_idc(profile_idc) + .picture_layout(vk::VideoDecodeH264PictureLayoutFlagsKHR::PROGRESSIVE), + )); + + let chroma_subsampling = match sps.chroma_info.chroma_format { + h264_reader::nal::sps::ChromaFormat::YUV420 => { + vk::VideoChromaSubsamplingFlagsKHR::TYPE_420 + } + h264_reader::nal::sps::ChromaFormat::Monochrome + | h264_reader::nal::sps::ChromaFormat::YUV422 + | h264_reader::nal::sps::ChromaFormat::YUV444 + | h264_reader::nal::sps::ChromaFormat::Invalid(_) => { + return Err(VulkanDecoderError::InvalidInputData(format!( + "unsupported chroma format: {:?}", + sps.chroma_info.chroma_format + ))) + } + }; + + let luma_bit_depth = if sps.chroma_info.bit_depth_luma_minus8 + 8 == 8 { + vk::VideoComponentBitDepthFlagsKHR::TYPE_8 + } else { + return Err(VulkanDecoderError::InvalidInputData(format!( + "unsupported luma bit length: {}", + sps.chroma_info.bit_depth_luma_minus8 + 8 + ))); + }; + + let chroma_bit_depth = if sps.chroma_info.bit_depth_chroma_minus8 + 8 == 8 { + vk::VideoComponentBitDepthFlagsKHR::TYPE_8 + } else { + return Err(VulkanDecoderError::InvalidInputData(format!( + "unsupported chroma bit length: {}", + sps.chroma_info.bit_depth_chroma_minus8 + 8 + ))); + }; + + let h264_info_ptr = h264_profile_info as *mut _; + let profile_info = vk::VideoProfileInfoKHR::default() + .video_codec_operation(vk::VideoCodecOperationFlagsKHR::DECODE_H264) + .chroma_subsampling(chroma_subsampling) + .luma_bit_depth(luma_bit_depth) + .chroma_bit_depth(chroma_bit_depth) + .push_next(h264_profile_info); + + Ok(Self { + profile_info, + h264_info_ptr, + }) + } +} + +impl<'a> Drop for H264ProfileInfo<'a> { + fn drop(&mut self) { + unsafe { + let _ = Box::from_raw(self.h264_info_ptr); + } + } +} + pub(crate) struct VkPictureParameterSet { pub(crate) pps: vk::native::StdVideoH264PictureParameterSet, } diff --git a/vk-video/src/vulkan_decoder/wrappers/video.rs b/vk-video/src/vulkan_decoder/wrappers/video.rs index e548f6ea8..7c3757820 100644 --- a/vk-video/src/vulkan_decoder/wrappers/video.rs +++ b/vk-video/src/vulkan_decoder/wrappers/video.rs @@ -2,7 +2,7 @@ use std::sync::Arc; use ash::vk; -use crate::{vulkan_decoder::VulkanDecoderError, VulkanCtx}; +use crate::{vulkan_decoder::VulkanDecoderError, VulkanDevice}; use super::{Device, MemoryAllocation, VideoQueueExt}; @@ -96,7 +96,7 @@ pub(crate) struct VideoSession { impl VideoSession { pub(crate) fn new( - vulkan_ctx: &VulkanCtx, + vulkan_ctx: &VulkanDevice, profile_info: &vk::VideoProfileInfoKHR, max_coded_extent: vk::Extent2D, max_dpb_slots: u32, @@ -185,6 +185,26 @@ impl Drop for VideoSession { } } +impl From for vk::native::StdVideoDecodeH264ReferenceInfo { + fn from(picture_info: crate::parser::ReferencePictureInfo) -> Self { + vk::native::StdVideoDecodeH264ReferenceInfo { + flags: vk::native::StdVideoDecodeH264ReferenceInfoFlags { + __bindgen_padding_0: [0; 3], + _bitfield_align_1: [], + _bitfield_1: vk::native::StdVideoDecodeH264ReferenceInfoFlags::new_bitfield_1( + 0, + 0, + picture_info.LongTermPicNum.is_some().into(), + picture_info.non_existing.into(), + ), + }, + FrameNum: picture_info.FrameNum, + PicOrderCnt: picture_info.PicOrderCnt, + reserved: 0, + } + } +} + impl From for vk::native::StdVideoDecodeH264ReferenceInfo { fn from(picture_info: crate::parser::PictureInfo) -> Self { vk::native::StdVideoDecodeH264ReferenceInfo { @@ -199,7 +219,7 @@ impl From for vk::native::StdVideoDecodeH264Referenc ), }, FrameNum: picture_info.FrameNum, - PicOrderCnt: picture_info.PicOrderCnt, + PicOrderCnt: picture_info.PicOrderCnt_as_reference_pic, reserved: 0, } }