diff --git a/.github/workflows/xbox-host-ci.yml b/.github/workflows/xbox-host-ci.yml index b57fe29..d218a2e 100644 --- a/.github/workflows/xbox-host-ci.yml +++ b/.github/workflows/xbox-host-ci.yml @@ -24,6 +24,9 @@ on: - ".github/workflows/xbox-host-ci.yml" workflow_dispatch: +permissions: + contents: read + env: # コンパイル検証に使う V8 ヘッダのバージョン (README「V8 の用意」と揃える) V8_TAG: 13.7.152.19 @@ -39,7 +42,7 @@ jobs: git clone --depth 1 --branch "$V8_TAG" --filter=blob:none --sparse \ https://github.com/v8/v8.git v8_headers cd v8_headers && git sparse-checkout set include - - name: Run raster tests + ASan + V8 syntax check + - name: Run raster/stb tests + ASan + V8 syntax check working-directory: templates/xbox run: tests/check_local.sh "$GITHUB_WORKSPACE/v8_headers/include" @@ -75,6 +78,14 @@ jobs: if errorlevel 1 exit /b 1 raster_test.exe + - name: Build & run stb safety regression tests + shell: cmd + working-directory: templates/xbox + run: | + cl /nologo /std:c++17 /EHsc /W3 /O1 tests\stb_safety_test.cpp /Fe:stb_safety_test.exe + if errorlevel 1 exit /b 1 + stb_safety_test.exe + - name: Build & run Windows platform tests (WIC/DirectWrite/MF/XAudio2/stb/dr) shell: cmd working-directory: templates/xbox diff --git a/.npmignore b/.npmignore index 25f2d55..1465056 100644 --- a/.npmignore +++ b/.npmignore @@ -4,4 +4,5 @@ src .gitattributes .gitignore eslint.config.mjs -tsconfig.json \ No newline at end of file +tsconfig.json +docs \ No newline at end of file diff --git a/README.md b/README.md index 3186dd8..3841cca 100644 --- a/README.md +++ b/README.md @@ -1,77 +1,108 @@ -Multi-platform Builder -============= +# Multi-platform Builder [![CodeQL](https://github.com/Next2D/builder/actions/workflows/github-code-scanning/codeql/badge.svg?branch=main)](https://github.com/Next2D/builder/actions/workflows/github-code-scanning/codeql) [![Lint](https://github.com/Next2D/builder/actions/workflows/lint.yml/badge.svg?branch=main)](https://github.com/Next2D/builder/actions/workflows/lint.yml) [![release](https://img.shields.io/github/v/release/Next2D/builder)](https://github.com/Next2D/builder/releases) [![license](https://img.shields.io/github/license/Next2D/builder)](https://github.com/Next2D/builder/blob/main/LICENSE) -[日本語]\ -1つのプロジェクトから多種多様なプラットフォーム向けのアプリケーションを作成するマルチプラットフォームビルダー。 - -* Steam:Steamに対応したWindows版、macOS版、Linux版のアプリケーションの書き出しが可能。 -* デスクトップ:デスクトップ環境向けに、Windows、macOS、Linux向けのアプリケーションを出力できます。 -* スマートフォン:iOSおよびAndroidに対応したスマートフォン用アプリケーションとしての書き出しもサポート。 -* Web(HTML):ブラウザ上で動作するHTML形式のコンテンツも簡単に生成可能。 - -Next2D Frameworkを使えば、1つのソースコードから多様なデバイスやOSに最適化されたアプリケーションを効率的に開発・展開することができます。 - -[English]\ -Multi-platform builder to create applications for a wide variety of platforms from a single project. - -* Steam: Allows export of applications for Windows, macOS, and Linux versions that are compatible with Steam. -* Desktop: Export of applications for Windows, macOS, and Linux for desktop environments is supported. -* Smartphone: Export as smartphone applications compatible with iOS and Android is also supported. -* Web (HTML): Easily generate HTML-format content that runs in a browser. - -With Next2D Framework, you can efficiently develop and deploy applications optimized for diverse devices and operating systems from a single source code. - -## Supported - -| platform | detail | -|-----------------|-------------------------------------| -| Windows | Export an exe file | -| macOS | Export dmg, app file | -| Linux | Export deb file | -| Steam:Windows | Export an exe file | -| Steam:macOS | Export dmg, app file | -| Steam:Linux | Export deb file | -| web | Export minfy'd JS files | -| iOS | open Xcode, and Export ipa | -| iOS | open Android Studio, and Export apk | -| Xbox | GDK native title (V8 + Dawn/WebGPU) | - -Xbox exports a GDK native title that runs the Next2D JavaScript on the V8 engine and -renders with Dawn (WebGPU → D3D12), packaged as a C++ executable (no Electron/WebView). -Building the GDK package requires Windows + Visual Studio 2022 + Microsoft GDK + a devkit. -On other platforms the builder scaffolds the host project and stages assets only. -See the generated `xbox/README.md` for full build steps. - -```bat -npx @next2d/builder --platform xbox --env prd +[日本語](#日本語) | [English](#english) + +## 日本語 + +Next2D Frameworkの1つのプロジェクトから、複数のプラットフォーム向けにアプリケーションを書き出すビルダーです。 +Steamおよびデスクトップ向けのWindows / macOS / Linux、スマートフォン向けのiOS / Android、Web(HTML)に対応しています。 +Xbox対応は試作・開発段階です。 + +### 対応プラットフォーム + +| プラットフォーム | 出力・対応状況 | +|---|---| +| Steam:Windows | 実行ファイル(.exe)と必要なリソース | +| Steam:macOS | アプリケーションバンドル(.app) | +| Steam:Linux | 実行ファイルと必要なリソース | +| Web | 最適化されたJavaScriptとWebアセット | +| iOS | Xcodeプロジェクトを開く、IPAを書き出す | +| Android | Android Studioプロジェクトを開く、APKを書き出す | +| Xbox | GDKネイティブホストの試作・開発段階 | + +### プラットフォーム別ガイド + +設定、依存ツール、書き出し・配布手順の詳細は、以下のドキュメントにまとめています。 + +| ガイド | 内容 | +|---|---| +| [Electron / Steam](docs/steam.md#日本語) | デスクトップ書き出し、アイコン、CPU、署名、Steam Depot、アップロード、ベータテスト | +| [iOS / Android(Capacitor)](docs/capacitor.md#日本語) | ネイティブ設定、SDK、プラグイン、ビルドコマンド、移行、Xcodeの設定 | +| [Xbox(試作)](docs/xbox.md#日本語) | 開発状況、ホスト生成、ビルド環境、検証範囲 | + +### 今後の対応予定 + +| プラットフォーム | +|---| +| Nintendo Switch | + +### ビルド例 + +```sh +npx @next2d/builder --platform web --env prd ``` -The prebuilt V8 engine is downloaded automatically on the first Xbox build -(published from the `build-v8` workflow). To use your own build, pass -`--v8-root C:\path\to\v8`. +### プレビュー例 -### Scheduled introduction +```sh +npx @next2d/builder --preview --platform web --env prd +``` + +### ライセンス + +このプロジェクトは[MIT License](https://opensource.org/licenses/MIT)で公開しています。詳細は[LICENSE](LICENSE)を参照してください。 + +## English + +Build applications for multiple platforms from a single Next2D Framework project. +The builder supports Windows / macOS / Linux for Steam and desktop distribution, iOS / Android for mobile devices, and Web (HTML). +Xbox support is a prototype under development. + +### Supported platforms -| platform | -|-----------------| +| Platform | Output / status | +|---|---| +| Steam:Windows | Executable (.exe) and required resources | +| Steam:macOS | Application bundle (.app) | +| Steam:Linux | Executable and required resources | +| Web | Optimized JavaScript and web assets | +| iOS | Open the Xcode project and export an IPA | +| Android | Open the Android Studio project and export an APK | +| Xbox | Prototype GDK native host; under development | + +### Platform guides + +These guides cover platform-specific configuration, dependencies, builds and distribution. + +| Guide | Contents | +|---|---| +| [Electron / Steam](docs/steam.md#english) | Desktop exports, icons, architectures, signing, Steam depots, uploads and beta testing | +| [iOS / Android (Capacitor)](docs/capacitor.md#english) | Native configuration, SDKs, plugins, build commands, migration and Xcode setup | +| [Xbox (prototype)](docs/xbox.md#english) | Development status, host generation, build environment and validation scope | + +### Planned support + +| Platform | +|---| | Nintendo Switch | -### build example. +### Build example -```linux +```sh npx @next2d/builder --platform web --env prd ``` -### preview example. +### Preview example -```linux +```sh npx @next2d/builder --preview --platform web --env prd ``` -## License -This project is licensed under the [MIT License](https://opensource.org/licenses/MIT) - see the [LICENSE](LICENSE) file for details. \ No newline at end of file +### License + +This project is licensed under the [MIT License](https://opensource.org/licenses/MIT). See [LICENSE](LICENSE) for details. diff --git a/docs/capacitor.md b/docs/capacitor.md new file mode 100644 index 0000000..f463ecb --- /dev/null +++ b/docs/capacitor.md @@ -0,0 +1,201 @@ +# iOS / Android(Capacitor) + +[日本語](#日本語) | [English](#english) + +## 日本語 + +### STEP1:対象OSのIDE・SDKを用意する + +| 対象 | ユーザーが用意するもの | +|---|---| +| iOS | macOS、Xcode本体とiOS SDK。Xcodeを初回起動してセットアップを完了する。 | +| Android | Android Studio、Android SDK、使用するCapacitorに対応したJDK。 | +| 実機・配布ビルド | 対象端末と、その配布方法に必要な署名証明書・プロビジョニング設定またはAndroidの署名鍵。 | + +使用するCapacitorのバージョンはbuilderの `src/tool-packages.ts` で固定している。 +対応するネイティブ環境は[Capacitorの開発フロー](https://capacitorjs.com/docs/basics/workflow)から確認する。 +Capacitorの `cli`・`core`・`ios`・`android` はbuilderが同じバージョンで取得するため、手動インストールは不要。 + +#### iOS:Xcodeの選択を確認する + +```sh +xcode-select -p +xcodebuild -version +``` + +`/Library/Developer/CommandLineTools` が選択されていると、IPA生成時に `xcodebuild requires Xcode` で失敗する。 +今回のシェルだけXcodeを指定する場合は、次を設定してからSTEP3へ進む: + +```sh +export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer +xcodebuild -version +``` + +システム全体の既定を変える場合は、代わりに次を使う: + +```sh +sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer +xcodebuild -version +``` + +Xcodeの配置先が異なる場合はパスを変更する。builderは呼び出し元の `DEVELOPER_DIR` を引き継ぐ。 +[Appleのコマンドラインツール設定](https://developer.apple.com/documentation/xcode/configuring-command-line-tools-settings) + +### STEP2:アプリ設定とプラグインを用意する + +ゲームルートの `capacitor.config.json` にアプリ固有の値を設定する。 + +```json +{ + "appId": "app.example.game", + "appName": "My Game", + "webDir": "dist/ios/prd/" +} +``` + +| 項目 | 設定・管理方法 | +|---|---| +| `appId` / `appName` | 自分のアプリ識別子・表示名に変更する。 | +| `webDir` | builderが今回のWeb出力先に更新するため、OSごとの手動切り替えは不要。 | +| `ios.path` / `android.path` | 必要な場合だけネイティブプロジェクトのカスタム出力先を指定する。 | +| ゲーム固有のCapacitor/Cordovaプラグイン | ゲームの依存として管理する。ゲーム側のフックも引き続き使用する。 | +| `@capacitor/core` | ゲームのJavaScriptで直接importする場合だけ、builderのCapacitorと互換性のあるバージョンをゲームの直接依存に追加する。 | + +その他の項目は[Capacitor設定](https://capacitorjs.com/docs/config)を参照。 + +### STEP3:ネイティブプロジェクトを開き、署名・アイコンを設定する + +対象OSのコマンドを実行する。 + +```sh +npx @next2d/builder --platform ios --env prd --open +npx @next2d/builder --platform android --env prd --open +``` + +未作成の `ios/` / `android/` を生成し、Web資産とネイティブ依存を同期してIDEを開く。 +Xcode / Android Studioで、アプリのアイコン・署名・配布方法に必要な設定を行う。 +これらのネイティブプロジェクトはゲーム側で保持する。再実行時も既存の設定・ネイティブコードを維持する。 + +### STEP4:ビルドして対象環境で確認する + +```sh +npx @next2d/builder --platform ios --env prd --build +npx @next2d/builder --platform android --env prd --build +``` + +実行前にWeb資産・ネイティブ依存を再同期する。対象端末やシミュレーター/エミュレーターで起動・入力・保存を確認する。 +Capacitorの `cap run` を使う場合は `--build` を `--preview` に置き換える。 +途中のコマンドが失敗した場合はbuilderも失敗する。 + +テンプレートのnpmスクリプト `open:ios` / `open:android` / `build:ios` / `build:android` も使用できる。 +環境指定は `npm run build:ios -- --env prd` のように渡す。 + +### 補足:既存プロジェクトの移行とSDKキャッシュ + +1. ゲームから不要になった `@capacitor/cli`・`@capacitor/ios`・`@capacitor/android` の直接依存を外す。 + `@capacitor/core` とゲーム固有プラグインはSTEP2の条件に従う。 +2. 設定と `ios/` / `android/` は保持し、STEP3でネイティブ依存の参照先を再同期する。 + +builderはゲームルートでCapacitor CLIを実行し、取得したSDKのパスを子プロセスの `NODE_PATH` に追加する。 +通常・ネストされたnpm依存配置や `file:../builder` に対応し、ゲーム側の補助スクリプトやSDKシンボリックリンクは不要。 +SDKキャッシュは書き出し後もGradle / CocoaPodsが参照するため保持する。 +npxキャッシュを削除した場合は、STEP3またはSTEP4で参照先を再同期する。 + +## English + +### STEP1: Prepare the platform IDE and SDK + +| Target | What you need to prepare | +|---|---| +| iOS | macOS, the full Xcode application and the iOS SDK. Complete Xcode's first-launch setup. | +| Android | Android Studio, the Android SDK and a JDK compatible with the Capacitor version in use. | +| Device and distribution builds | Target devices and signing certificates/provisioning settings or an Android signing key, as required by the distribution method. | + +The builder pins the Capacitor version in `src/tool-packages.ts`. +Check the corresponding native environment through the [Capacitor development workflow](https://capacitorjs.com/docs/basics/workflow). +The builder acquires matching versions of Capacitor's `cli`, `core`, `ios` and `android`; no manual installation is needed. + +#### iOS: Check the selected Xcode + +```sh +xcode-select -p +xcodebuild -version +``` + +If `/Library/Developer/CommandLineTools` is selected, IPA generation fails with `xcodebuild requires Xcode`. +To select Xcode for the current shell, set this before STEP3: + +```sh +export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer +xcodebuild -version +``` + +Alternatively, to change the system-wide default: + +```sh +sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer +xcodebuild -version +``` + +Adjust the path if Xcode is installed elsewhere. The builder inherits the caller's `DEVELOPER_DIR`. +[Apple's command-line tools settings](https://developer.apple.com/documentation/xcode/configuring-command-line-tools-settings) + +### STEP2: Prepare app configuration and plugins + +Set game-specific values in `capacitor.config.json` at the game root. + +```json +{ + "appId": "app.example.game", + "appName": "My Game", + "webDir": "dist/ios/prd/" +} +``` + +| Setting | Configuration / ownership | +|---|---| +| `appId` / `appName` | Replace with your app identifier and display name. | +| `webDir` | The builder updates this to the current web output directory; no manual switching between operating systems is needed. | +| `ios.path` / `android.path` | Set only when using custom native project locations. | +| Game-specific Capacitor/Cordova plugins | Keep them in the game's dependencies. Game hooks continue to work. | +| `@capacitor/core` | Add a compatible version as a direct game dependency only when the game's JavaScript imports it directly. | + +See [Capacitor configuration](https://capacitorjs.com/docs/config) for other settings. + +### STEP3: Open the native project and configure signing and icons + +Run the command for your target OS: + +```sh +npx @next2d/builder --platform ios --env prd --open +npx @next2d/builder --platform android --env prd --open +``` + +The builder creates missing `ios/` / `android/` projects, synchronizes web assets and native dependencies, then opens the IDE. +Configure app icons, signing and distribution-specific settings in Xcode / Android Studio. +Keep these native projects in the game. Subsequent runs preserve existing settings and native code. + +### STEP4: Build and verify on the target environment + +```sh +npx @next2d/builder --platform ios --env prd --build +npx @next2d/builder --platform android --env prd --build +``` + +Web assets and native dependencies are synchronized before building. Verify launch, input and saved data on target devices or simulators/emulators. +Replace `--build` with `--preview` to use Capacitor's `cap run`. +If any command fails, the builder fails as well. + +Template npm scripts `open:ios` / `open:android` / `build:ios` / `build:android` are also available. +Pass the environment as in `npm run build:ios -- --env prd`. + +### Reference: Existing project migration and SDK cache + +1. Remove direct dependencies on `@capacitor/cli`, `@capacitor/ios` and `@capacitor/android` that are no longer needed by the game. + Follow STEP2 for `@capacitor/core` and game-specific plugins. +2. Keep the configuration and `ios/` / `android/`, then use STEP3 to resynchronize native dependency paths. + +The builder runs the Capacitor CLI from the game root and adds acquired SDK paths to the child process's `NODE_PATH`. +Regular and nested npm dependency layouts and `file:../builder` are supported; no game-side helper scripts or SDK symlinks are needed. +Keep the SDK cache after export because Gradle / CocoaPods reference it. +If you delete the npx cache, use STEP3 or STEP4 to resynchronize those paths. diff --git a/docs/steam.md b/docs/steam.md new file mode 100644 index 0000000..90bb47f --- /dev/null +++ b/docs/steam.md @@ -0,0 +1,714 @@ +# Steam 書き出し / アップロード / Export / Upload + +[日本語](#日本語) | [English](#english) + +## 日本語 + +ローカルへの書き出しだけなら、Steamworks・SteamCMD・配布用の署名認証は不要。 + +### STEP1:対象OSの実行環境とアイコンを用意する + +- macOSのUniversalアプリと配布用の署名・公証はmacOS上で行う。 +- Next2D Frameworkのテンプレートの `src/assets/icons/` にWindows用ICO、macOS用ICNS、Linux用PNGを用意する。 + テンプレートの仮アイコンは配布前に差し替える。設定の省略時の扱いはSTEP3の表を参照。 + +#### 対応OS・CPU + +| OS | 既定値 | `architectures` / `--arch` の対応値 | +|---|---|---| +| Windows | `x64` | `x64`, `arm64` | +| macOS | `universal` | `x64`, `arm64`, `universal` | +| Linux | `x64` | `x64`, `arm64` | + +### STEP2:SteamworksのApp・Depot・テスト用ブランチを用意する(Steam配布時) + +1. 対象アプリのSteamworks管理画面で、発行済みのApp IDを確認する。 +2. SteamPipe > DepotsでDepotを作成し、対象OSを設定する。言語共通ならAll languagesを選び、 + Save Changesで保存後、公開(Publish)タブで変更を反映する。 + 開発用・テスト用・販売用Packageにも必要なDepotを含める。**Depot IDはApp IDから推測せず、実際の値を使う。** +3. SteamPipe > Buildsで `internal` ブランチを作成し、**パスワードを設定して関係者だけに共有する。** + 名前だけでは非公開にならず、builderはブランチ作成・パスワード設定や確認を行わない。 +4. テスターにゲームと対象Depotの利用権を用意する。未発売ゲームの外部テスターには + Release State Override(beta)キー等を使う。ブランチのパスワードだけでは利用権は付与されない。 + パスワードを第三者に共有しないよう運用し、JSONやリポジトリにも保存しない。 + +#### 複数Depotの構成とbuilderの対応範囲 + +**Steamでは1つのApp IDに複数Depotを設定できる。** OS固有ファイルはOS別Depotに分ける構成をValveが推奨している。 + +| 構成 | Steam | 現在のbuilder | +|---|---|---| +| Windows / macOS / Linuxを別Depotにする | 対応。各Depotの対象OSを指定する。 | 対応。`steam.depots` の各OSに異なる発行済みIDを設定する。 | +| 複数OSを1つのDepotにまとめる | 対応。対象OSをAll OSesなど構成に合わせる。 | 対応。対象OSに同じIDを設定する。各OSのファイルをサブディレクトリに分ける。全対象OSのファイルを配布するため容量が増える。 | +| 一部OSだけ同じDepotにする | 対応。 | 対応。共有するOSだけ同じIDにする。 | +| 同じOS向けに本体・共通アセット・言語などを複数Depotに分ける | 対応。複数Depotの内容をインストール時に組み合わせる。 | 未対応。各OSの値は単一のDepot IDで、配列や追加アセット用キーには対応しない。 | + +builderの設定可能数は各OSに1 ID、全体で最大3つの異なるID。この上限はbuilderの設定形式によるもので、Steamの上限ではない。 +OSごとの成果物を揃える手順と起動パスはSTEP5、複数Depotを1回でアップロードする手順はSTEP6を参照する。 + +Steam側のダウンロード対象はPackageの利用権とDepotのOS・言語などの条件で決まる。 +同時にインストールするDepotで同じパスが重なると、Depot一覧の後にあるものが優先されるため、ファイルの配置を確認する。 +これらの選択条件はSteamworks側で設定し、builderのJSONからは反映しない。 + +`internal` / `beta` はAppのビルドを選ぶブランチで、ブランチごとに別Depotを作る必要はない。 +また、この文書の「共有Depot」は同一App内で複数OSをまとめる意味。 +Steamworksの「Add Shared Depot」は別AppのDepotを参照する機能であり、builderの同一ID指定とは別の操作。 + +[Depotの設定](https://partner.steamgames.com/doc/store/application/depots) / +[Packageと利用権](https://partner.steamgames.com/doc/store/application/packages) / +[複数Depotのアップロード](https://partner.steamgames.com/doc/sdk/uploading) / +[betaブランチ](https://partner.steamgames.com/doc/store/application/branches) / +[Steamでのテスト](https://partner.steamgames.com/doc/store/testing) / +[Release State Overrideキー](https://partner.steamgames.com/doc/features/keys) + +### STEP3:electron.config.jsonを設定する + +プロジェクトルートの `electron.config.json` でゲーム固有設定を管理する。 +JavaScript / TypeScriptの両テンプレートに含まれるので、初期値を自分のゲームの値に変更する。 +`appId` は macOS bundle ID・保存先識別子、`steam.appId` は Valve の数値 App ID。 +これらは別のID。バージョンはゲームルートの `package.json` を使う。 + +```json +{ + "appId": "app.example.game", + "appName": "My Game", + "executableName": "my-game", + "companyName": "Example Company", + "icons": { + "windows": "src/assets/icons/icon.ico", + "macos": "src/assets/icons/icon.icns", + "linux": "src/assets/icons/icon.png" + }, + "architectures": { "windows": "x64", "macos": "universal", "linux": "x64" }, + "window": { "width": 1280, "height": 720, "fullscreen": false }, + "steam": { + "appId": null, + "branch": "internal", + "depots": { "windows": null, "macos": null, "linux": null } + }, + "macos": { "sign": false, "notarize": false } +} +``` + +| 項目 | 用途・仕様 | 省略時・注意点 | +|---|---|---| +| `companyName` | Windows実行ファイルの会社名。 | 省略時は `package.json` の `author.name`、なければゲーム名。 | +| `appName` / `executableName` | `appName` はウィンドウ・アプリケーション名。`executableName` は実行ファイル名。 | 表示名と実行ファイル名を個別に設定できる。 | +| `description` | 任意の説明文。生成するElectronホストの `package.json` とWindowsのファイル説明に反映する。 | JSONの値を優先。未指定または `null` ならルートの `package.json` の `description` を使う。両方未指定なら空文字。明示的な `""` も空文字として扱う。 | +| `icons` | アイコン画像のパス。プロジェクトルートからの相対パス、または絶対パスを指定する。WindowsはICO、macOSはICNS、LinuxはPNG。 | 各キーは省略可。省略したOSにはbuilder同梱の仮のNext2Dアイコンを使う。`"icons": {}` なら全OSで仮アイコンを使える。指定したファイルがなければ失敗する。 | +| `architectures` | OSごとのCPU設定。対応値はSTEP1の「対応OS・CPU」を参照。 | 省略時はWindows/Linuxが `x64`、macOSが `universal`。`--arch` が優先する。 | +| `steam.appId` | Valveの数値App ID。未発行なら `null` を指定する。 | 未発行でもローカル書き出しは可能。SteamPipe用VDFは生成しない。 | +| `steam.branch` | `--steam-upload` の反映先betaブランチ。 | 省略時は `internal`。`--steam-branch` が優先する。ブランチの作成・パスワード設定はSteamworks側で行う。 | +| `steam.depots` | Steamworksで作成した実際のDepot ID。複数OSに同じIDを指定すると、同一Depotへまとめて配布する。 | App IDから推測しない。`null` / 未指定ならアプリと起動情報だけを生成し、アップロード用VDFは生成しない。 | +| `macos` | macOSアプリの署名・公証設定。 | ローカル検証用は `sign` / `notarize` ともに `false`。本番配布では両方を有効化する。 | + +### STEP4:署名・アップロードの認証を用意する(配布時) + +#### macOSの署名・公証 + +macOSのキーチェーンにDeveloper ID Application証明書と対応する秘密鍵を登録し、 +`xcrun notarytool store-credentials` で公証用プロファイルを保存する。認証情報はJSONへ書かない。 + +`APPLE_SIGNING_IDENTITY` に指定する署名IDは、次のコマンドで確認できる。 + +```sh +security find-identity -v -p codesigning +``` + +表示された有効な署名IDから `Developer ID Application: ...` を選び、ダブルクォート内の名前全体を +`APPLE_SIGNING_IDENTITY` に指定する。以下の `YOUR NAME (TEAMID)` は実際の表示に置き換える。 +環境変数を設定するだけでは証明書は作成されない。 + +```sh +export APPLE_SIGNING_IDENTITY='Developer ID Application: YOUR NAME (TEAMID)' +export APPLE_NOTARY_PROFILE='your-notary-profile' +``` + +配布用は `macos.sign` / `macos.notarize` を両方 `true` にする。 +またはSTEP5のmacOSコマンドに `NEXT2D_STEAM_RELEASE=1` を付けると、JSONのfalse指定に関わらず両方を必須にできる。 +認証情報不足・署名失敗・公証失敗はビルド失敗となる。 +署名エラーは公証へ進まずに停止する。`Signature=adhoc` / `TeamIdentifier=not set` が出る場合は、 +Developer ID署名が付いていないため、先に表示された署名エラーとキーチェーンの証明書・秘密鍵を確認する。 + +Steam用のターゲットは `darwin`。Valveは新規macOSアプリに64bitとAppleの公証を要求する。 +テンプレートのentitlementsはJITとSteam Overlay用のlibrary validation / DYLD設定を含み、 +`com.apple.security.app-sandbox` は付けない(Chromiumのrenderer sandboxとは別)。 +[Valveのプラットフォーム要件](https://partner.steamgames.com/doc/store/application/platforms) / +[Electron Packagerの署名・公証設定](https://electron.github.io/packager/main/interfaces/Options.html) + +#### SteamCMDとビルドアカウント + +[Steamworks SDKのContentBuilder](https://partner.steamgames.com/doc/sdk/uploading)にある実行OS用のSteamCMDを用意する。 +Windowsは `steamcmd.exe`、macOS / Linuxは `steamcmd.sh` を使用できる。 +PATH上の `steamcmd`(Windowsは `steamcmd.exe`)を使うか、環境変数 `STEAMCMD` に実行ファイルのパスを指定する。 +引数やシェルコマンドを含めず、パスだけを指定する。`.sh` は実行権限が必要。 +SteamCMD自体の実行に必要なOSライブラリはSteamCMDの手順に従って用意する。 + +アップロード用アカウントには対象アプリの `Edit App Metadata` と `Publish App Changes To Steam` の権限を付与する。 +macOS / Linuxの設定例(配置先とアカウント名を置き換える): + +```sh +export STEAMCMD="/absolute/path/to/steamcmd.sh" +export STEAM_USERNAME="your_build_account" +"$STEAMCMD" +login "$STEAM_USERNAME" +quit +``` + +初回ログインではSteamCMDにパスワードと、要求された場合はSteam Guardコードを対話入力する。 +ログイン成功後も、`+quit` による正常終了まで待ち、通常のターミナルのプロンプトに戻ったことを確認する。 +`Steam>` で手動ログインした場合も、`quit` を入力して終了してからアップロードへ進む。 +その後builderは同じSteamCMD・同じアカウントの保存済みログインを使い、パスワードをコマンド引数へ渡さない。 +Steamアプリへのログインだけでは、このSteamCMDの認証準備を完了したことにはならない。 + +アップロード時に `Cached credentials not found` / `No cached credentials and @NoPromptForPassword is set` が出た場合や、 +認証が失効した場合は、上の `"$STEAMCMD" +login "$STEAM_USERNAME" +quit` を再実行し、正常終了後にアップロードを再実行する。 +builderからの実行は対話入力を待たず失敗させるため、builderの再実行だけではログイン情報を登録できない。 +CIではSteamCMDの `config/config.vdf` をSecretとして復元・管理し、ビルド成果物に含めない。 +Windows PowerShellでは `$env:STEAMCMD` と `$env:STEAM_USERNAME` を設定する。 + +### STEP5:各OSを書き出し、成果物を揃える + +ゲームルートで必要なOSのコマンドを実行する。書き出しはアップロード・公開を行わない。 + +```sh +npx @next2d/builder --platform steam:windows --env prd +npx @next2d/builder --platform steam:macos --env prd +npx @next2d/builder --platform steam:linux --env prd +``` + +CPUを変える場合は `--arch arm64` などを追加する。 +テンプレートの `npm run build:steam:windows` / `build:steam:macos` / `build:steam:linux` も同じ処理を行い、 +`--env prd` を指定済み。npm経由の引数は `-- --arch arm64` や `-- --env dev` で渡す。 + +既定の出力先は `dist/steam//build//`。 + +| OS | 配布するフォルダ全体 | OS別DepotのExecutable | 共有DepotのExecutable | +|---|---|---|---| +| Windows | `My Game-win32-x64/` | `my-game.exe` | `windows/my-game.exe` | +| macOS | `My Game-darwin-universal/` | `My Game.app` | `macos/My Game.app` | +| Linux | `My Game-linux-x64/` | `my-game` | `linux/my-game` | + +実際の起動パス・CPU・ContentRootは `*-steampipe/launch.json` を参照する。 +実行ファイルだけでなく、Electronのライブラリ・locales・ライセンス・resourcesを含むフォルダ全体が配布対象。 +Steam用のDMG/DEB/MSIは不要で、書き出し後に追加のアプリビルドは行わない。 + +別マシンやCIの成果物は、`steam-package.json` と `*-steampipe/` を含む各OSの `build//` を +同じ `dist/steam//build//` 構成に集める。macOSのシンボリックリンクとLinuxの実行権限を保つため、 +CI artifactは `tar.gz` にして転送する。カスタム出力先はSTEP6の `--steam-root` で指定する。 + +設定・バージョンを変えたら対象OSを再書き出しする。同じバージョン番号でも全OSを意図したリビジョンで揃える。 +同じOSのx64とarm64を順に書き出すと、最後に成功したCPUの成果物を使う。 +同じOSの複数CPUを1つの共有Depotへ同時に統合する処理は行わない。 + +配布用macOSアプリは署名・公証・staple完了を確認する(パスは成果物に合わせる): + +```sh +codesign --verify --deep --strict --verbose=2 'dist/steam/macos/build/prd/My Game-darwin-universal/My Game.app' +echo $? +xcrun stapler validate 'dist/steam/macos/build/prd/My Game-darwin-universal/My Game.app' +echo $? +``` + +| 検証 | 正常時の出力 | 直後の `echo $?` | +| --- | --- | --- | +| `codesign --verify --deep --strict --verbose=2` | アプリのパスに続いて `valid on disk` と `satisfies its Designated Requirement` が表示される。内部コードの検証結果が追加で表示される場合もある。 | `0` | +| `xcrun stapler validate` | 最後に `The validate action worked!` が表示される。 | `0` | + +`codesign` は `--verbose=2` を付けない場合、成功しても通常は何も表示しない。終了コードが `0` なら検証成功と判断できる。 +`echo $?` は確認したいコマンドの直後に実行する。`0` 以外なら検証失敗なので、出力されたエラーを解消して再確認する。 +これらは署名と添付済み公証チケットを検証するコマンドであり、署名・公証を実施する操作ではない。 +両方が成功した後も、STEP6でSteamからのインストール・起動を確認する。 + +参考:[Appleの署名検証手順](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html)。 + +### STEP6:起動設定を反映し、アップロード・テストする + +SteamworksのInstallation > General InstallationにOS別Launch Optionを追加する。 +ExecutableはSTEP5の `launch.json` に合わせ、Arguments/Working Directoryは空欄にする。 +x64版は64bit条件を指定する。対応OS・最低OS要件は同梱Electronと実機検証に合わせ、Steamworksで変更をPublishする。 + +ゲームルートで次を実行する。共有Depot・OS別Depotをまとめて1回のAppBuildでアップロードする。 +Web/Electronの再ビルドや事前の `--steam-manifest` 実行は不要。 + +```sh +# ローカル検証のみ。SteamCMD・認証・Steamへの接続は不要 +npx @next2d/builder --steam-upload --env prd --dry-run + +# STEP4のSteamCMDログイン・正常終了後、同じターミナルで設定したブランチへアップロード +npx @next2d/builder --steam-upload --env prd +``` + +任意のアップロードコメントを付ける場合は `--steam-comment` を指定する。 +Steamworksの「あなたのビルド」の説明(SteamPipeの `Desc`)に反映される。 + +```sh +npx @next2d/builder --steam-upload --env prd --steam-comment "内部テスト:ゲームパッド操作を修正" +``` + +| 引数・設定 | 用途 | +|---|---| +| `--steam-branch internal` | `steam.branch` の反映先を上書き。`SetLive` で反映を要求する。`default` は指定不可で、一般公開用ビルドの切り替えはSteamworksで行う。 | +| `--steam-comment "コメント"` | アップロードコメントを指定する。未指定時は従来どおり ` (, )`。空白のみ・改行・制御文字・ダブルクォート・バックスラッシュは使用不可。`--dry-run` の出力と `upload-plan.json` でも確認できる。 | +| `--steam-root dist/steam` | 成果物の収集先。既定は `dist/steam`。ゲームルートからの相対パスまたは絶対パス。アップロード時はVite設定を読まないため、カスタム出力先では明示する。 | +| `--dry-run` | パッケージと設定の整合性を検証する。Steam側の権限・ブランチ・パスワードの確認は行わない。 | +| 併用しない引数 | `--build` / `--preview` / `--open` / `--steam-manifest` / `--arch`。`--platform` も不要。 | + +対応するテンプレートのnpmスクリプトは `upload:steam:check` / `upload:steam`。 + +builderは `steam.depots` に設定された全OSの `steam-package.json` と実行ファイルを検証し、 +App ID・Depot ID・バージョン・ゲーム名・CPUに不足や不整合があればSteamCMD起動前に停止する。 +VDFは検証結果から再生成する。通常の書き出し用VDFは変更しない。 + +| 保存先(`--steam-root` 配下) | 内容 | +|---|---| +| `uploads//-<識別子>/` | VDF、`upload-plan.json`。dry-runは `Preview=1`、`SetLive`なし。アップロード成功時はBuildIDを `upload-result.json` に記録。 | +| `uploads//cache//` | SteamPipeのログ・差分キャッシュ。 | + +SteamworksのBuilds画面で、記録されたBuildIDが対象ブランチの現在のビルドになっていることを確認する。 +アカウントやアプリの状態によってSteam側の追加確認が必要になる場合がある。 +テスターはSteamクライアントのプロパティ > ゲームバージョンとベータでパスワードを入力し、`internal` を選ぶ。 +各OSでインストール・起動を確認し、macOS UniversalはIntel / Apple Siliconの両方でテストする。 + +### 参照:VDFの生成と手動アップロード + +builderのSTEP6を使う場合、この節の操作は不要。SteamCMDを直接操作する場合に使う。 + +| 構成 | 通常の書き出し時のVDF生成先・条件 | +|---|---| +| OS別Depot | 各OSの `*-steampipe/`。 | +| 共有Depot | 全対象OSが揃うと `dist/steam/shared//depot-/`。不足OSは `launch.json` に記録し、アップロード用VDF・OS単独VDFは生成しない。 | + +一部OSだけDepot IDを共有する構成にも対応する。`FileMapping` でOS別サブディレクトリへ配置し、アセットは再コピーしない。 +別マシンの成果物を集めた後に共有DepotのVDFだけを再生成する場合: + +```sh +npx @next2d/builder --platform steam:macos --env prd --steam-manifest +``` + +npmの別名は `build:steam:manifest`(別環境なら `-- --env dev`)。このコマンドはどのOSでも実行でき、 +`--platform` はVite設定を読むための指定で、設定内のすべての共有Depotを統合する。 +`build.outDir` と `--env` から最新の成功した書き出しを選び、App ID・Depot ID・ゲーム名・実行ファイル名・バージョンを検証する。 +不足パッケージは終了コード1となり、古い統合VDFは再生成時に無効化する。 +`--arch` / `--preview` / `--build` / `--open` とは併用できない。 + +`app_preview.vdf` はファイルマッピング検証、`app_build.vdf` はアップロード、 +`depot_build.vdf` はフォルダ内容の再帰マッピング用。`steam_appid.txt` は配布対象から除外する。 +ContentRootはVDFからの相対パスなので、単独Depotはアプリと `*-steampipe/` をセットで、共有Depotは `dist/steam/` 全体の構成を保って移動する。 + +```text +steamcmd +login BUILD_ACCOUNT +run_app_build "/absolute/path/to/app_preview.vdf" +quit +steamcmd +login BUILD_ACCOUNT +run_app_build "/absolute/path/to/app_build.vdf" +quit +``` + +通常の書き出し・`--steam-manifest` のVDFには `SetLive` がないため、アップロード後にSteamworksで対象ブランチへ設定する。 +OS別VDFは1つのDepotを更新するので、最終BuildのDepot manifestが全OSで意図した版になっているか確認する。 +[SteamPipe公式手順・VDF仕様](https://partner.steamgames.com/doc/sdk/uploading) + +### 参照:テンプレート・ホスト・移行 + +`create-next2d-app` はプロジェクト名から `appId`、`appName`、`executableName`、 +`companyName` を設定する。例えば `my-game` なら `appId` は `app.example.my-game`、 +他の3項目は `my-game` になる。配布前にbundle IDと会社名を自分の値へ変更する。 +CPU設定が省略されている場合はOSごとの既定値を補い、テンプレートに指定済みの値は保持する。 +アイコンパスやSteam IDなどの設定も保持する。 + +Electron用コードはbuilderが管理する。OSの一時ディレクトリにホスト・runtime設定・Web資産を配置し、失敗時を含め書き出し後に削除する。 +ゲーム側へ `electron/`、Electron用 `node_modules` / lockfileは作らない。 +Electronは `templates/electron/package.json`、Packagerは `src/tool-packages.ts` の固定バージョンを取得・キャッシュする。 +PackagerはElectron書き出し時のみ取得し、OS別パッケージ・アイコン・署名・公証を処理する。 +ホストにはnpm依存やネイティブアドオンがないため、ABIに合わせた再ビルドは不要。 +プレビューは実行ホストのOS/CPUで書き出した `dist//build//` のアプリを起動する。 + +旧 `electron/` のホストコード・`config.forge`・独自npm依存は参照しない。 +移行時はアイコンを共通アセットへ移し、JSONのパスを更新してから旧ディレクトリを削除する。 +独自main/preloadやネイティブアドオンがある場合は、先にbuilder側への対応が必要。 + +テンプレートのホストは絶対パスと固定origin `next2d://game` で資産を読む。 +起動時の作業ディレクトリに依存せず、ローカルfetch・Worker・localStorageが使える。 +F11/Alt+Enterで全画面、Escapeで解除。閉じるとmacOSでもプロセスを終了する。 +Node integration無効・context isolation/sandbox有効、外部ページ遷移と新規ウィンドウは禁止。 +Next2D用CSPを付与する。外部APIを使うゲームでは接続先を明示的に追加すること。 +[Electron security](https://www.electronjs.org/docs/latest/tutorial/security) / +[protocol](https://www.electronjs.org/docs/latest/api/protocol) + +保存先はElectronのappData配下の `appId` ディレクトリ。 +表示名を変えても保存先は変わらない。旧file-originの開発版セーブは自動移行しない。 +Steam Cloudは未統合。Chromiumプロファイル全体をCloud対象にせず、導入時は +ゲーム用のセーブファイルとアカウント単位の保存方式を別途設計する。 +[Steam Cloud](https://partner.steamgames.com/doc/features/cloud) + +### リリース前の確認範囲 + +STEP6のインストール・起動確認に加えて、以下を検証する。 + +- 終了動作、オフライン起動、更新後の保存データ。 +- マウス/キーボード/コントローラ、解像度・全画面切替、音声、スリープ復帰。 +- Shift+Tab Overlay。Electronは複数プロセスなので、OS/GPUごとに実動作を確認する。 + この書き出しはSteamworks SDK・実績・DRM・Overlay APIを統合しない。 + SDK統合はSteam配布の必須条件ではない。 +- LinuxはSteam Linux Runtime環境で依存ライブラリとsandboxを確認する。 + `--no-sandbox` を配布用の回避策にしない。 +- Steam DeckのVerified判定は別審査。Linux版が生成できたことだけでは対応完了にならない。 + コントローラだけで操作できること、文字の可読性、画面表示等を実機で確認する。 +- Steamのビルド審査前に、ストアで宣言したOS・機能と動作が一致することを確認する。 + +[Steamworks API](https://partner.steamgames.com/doc/sdk/api) / +[Overlay](https://partner.steamgames.com/doc/features/overlay) / +[Linux開発](https://partner.steamgames.com/doc/store/application/platforms/linux) / +[Steam Deck互換性](https://partner.steamgames.com/doc/steamhardware/compat) / +[ビルド審査](https://partner.steamgames.com/doc/store/review_process) + +## English + +Local exports do not require Steamworks, SteamCMD or distribution signing credentials. + +### STEP1: Prepare target environments and icons + +- Build macOS Universal applications and perform macOS signing/notarization on macOS. +- Place Windows ICO, macOS ICNS and Linux PNG icons in `src/assets/icons/` in the Next2D Framework template. + Replace template placeholders before distribution. STEP3 documents omitted icon settings. + +#### Supported operating systems and architectures + +| OS | Default | Accepted `architectures` / `--arch` values | +|---|---|---| +| Windows | `x64` | `x64`, `arm64` | +| macOS | `universal` | `x64`, `arm64`, `universal` | +| Linux | `x64` | `x64`, `arm64` | + +### STEP2: Prepare the Steamworks app, depots and testing branch (Steam distribution) + +1. Find the issued App ID in the app's Steamworks administration page. +2. Create depots in SteamPipe > Depots and select their operating systems. Use All languages for shared language content, + save with Save Changes, then apply the changes on the Publish tab. + Include the required depots in development, testing and retail Packages. **Use actual Depot IDs; do not infer them from the App ID.** +3. Create an `internal` branch in SteamPipe > Builds and **set a password shared only with the intended testers.** + The name alone does not make it private. The builder does not create branches, configure passwords or verify protection. +4. Give testers access to the game and its depots. For external testers of an unreleased game, use Release State Override + (beta) keys or another appropriate method. A branch password alone does not grant game access. + Keep the password out of JSON and the repository, and ask testers not to share it with others. + +#### Multiple depots and builder support + +**Steam supports multiple depots under one App ID.** Valve recommends separate depots for OS-specific files. + +| Configuration | Steam | Current builder | +|---|---|---| +| Separate depots for Windows / macOS / Linux | Supported. Set the target OS for each depot. | Supported. Assign different issued IDs to the OS entries in `steam.depots`. | +| One depot containing multiple operating systems | Supported. Set its OS selection accordingly, such as All OSes. | Supported. Assign the same ID to those operating systems. Files are placed in OS subdirectories. Distributing every included OS's files increases download size. | +| Only some operating systems share a depot | Supported. | Supported. Assign the same ID only to those operating systems. | +| Multiple depots for one OS, such as the application, common assets and languages | Supported. Their contents are combined during installation. | Not supported. Each OS accepts a single Depot ID; arrays and extra asset keys are not supported. | + +The builder accepts one ID per OS, for a maximum of three distinct IDs overall. This is a limit of the builder's configuration format, not a Steam limit. +See STEP5 for collecting OS packages and launch paths, and STEP6 for uploading multiple depots in one operation. + +Steam selects downloads based on Package ownership and depot conditions such as OS and language. +If simultaneously installed depots contain the same path, the depot later in the list takes priority, so check file placement. +Configure these selection conditions in Steamworks; the builder's JSON does not apply them. + +`internal` / `beta` are branches that select an app build; separate depots are not required for each branch. +In this document, a "shared depot" groups multiple operating systems within the same app. +Steamworks' "Add Shared Depot" references a depot from another app; it is a separate operation from assigning the same ID in the builder. + +[Depot configuration](https://partner.steamgames.com/doc/store/application/depots) / +[Packages and access](https://partner.steamgames.com/doc/store/application/packages) / +[Uploading multiple depots](https://partner.steamgames.com/doc/sdk/uploading) / +[Beta branches](https://partner.steamgames.com/doc/store/application/branches) / +[Testing on Steam](https://partner.steamgames.com/doc/store/testing) / +[Release State Override keys](https://partner.steamgames.com/doc/features/keys) + +### STEP3: Configure electron.config.json + +Manage game-specific settings in `electron.config.json` at the project root. +Both JavaScript and TypeScript templates include it; replace the defaults with your game's values. +`appId` is the macOS bundle ID and the identifier used for the save location; `steam.appId` is Valve's numeric App ID. +These are separate identifiers. The game version comes from the root `package.json`. + +```json +{ + "appId": "app.example.game", + "appName": "My Game", + "executableName": "my-game", + "companyName": "Example Company", + "icons": { + "windows": "src/assets/icons/icon.ico", + "macos": "src/assets/icons/icon.icns", + "linux": "src/assets/icons/icon.png" + }, + "architectures": { "windows": "x64", "macos": "universal", "linux": "x64" }, + "window": { "width": 1280, "height": 720, "fullscreen": false }, + "steam": { + "appId": null, + "branch": "internal", + "depots": { "windows": null, "macos": null, "linux": null } + }, + "macos": { "sign": false, "notarize": false } +} +``` + +| Field | Purpose / behavior | Defaults / notes | +|---|---|---| +| `companyName` | Company name in the Windows executable metadata. | Falls back to `author.name` in `package.json`, then to the game name. | +| `appName` / `executableName` | `appName` is the window and application name. `executableName` is the executable file name. | The display name and executable name can be set independently. | +| `description` | Optional description used in the generated Electron host's `package.json` and the Windows file description. | The JSON value takes priority. If omitted or `null`, uses `description` from the root `package.json`. If both are absent, uses an empty string. An explicit `""` also remains empty. | +| `icons` | Icon paths, relative to the project root or absolute. Use ICO for Windows, ICNS for macOS and PNG for Linux. | Each key is optional. Omitted platforms use the builder's placeholder Next2D icons; `"icons": {}` uses placeholders for every OS. A specified file that does not exist causes an error. | +| `architectures` | CPU architecture per OS. See STEP1 for supported operating systems and architectures. | Defaults to `x64` for Windows/Linux and `universal` for macOS. `--arch` takes priority. | +| `steam.appId` | Valve's numeric App ID. Set to `null` if it has not been issued. | Local exports still work without an App ID, but SteamPipe VDFs are not generated. | +| `steam.branch` | Target beta branch for `--steam-upload`. | Defaults to `internal`. `--steam-branch` takes priority. Create the branch and configure its password in Steamworks. | +| `steam.depots` | Actual Depot IDs created in Steamworks. Assigning the same ID to multiple operating systems combines them in one depot. | Do not infer Depot IDs from the App ID. If `null` or omitted, only the application and launch metadata are generated, without upload VDFs. | +| `macos` | macOS signing and notarization settings. | Use `false` for both `sign` / `notarize` during local testing. Enable both for production distribution. | + +### STEP4: Prepare signing and upload credentials (distribution) + +#### macOS signing and notarization + +Install a Developer ID Application certificate and its matching private key in the macOS keychain, and save a notarization profile using +`xcrun notarytool store-credentials`. Do not put credentials in JSON. + +Use the following command to find the signing identity to set as `APPLE_SIGNING_IDENTITY`: + +```sh +security find-identity -v -p codesigning +``` + +Choose a valid `Developer ID Application: ...` identity from the output and use the entire name inside the double quotes +for `APPLE_SIGNING_IDENTITY`. Replace `YOUR NAME (TEAMID)` below with the actual value shown. +Setting the environment variable does not create a certificate. + +```sh +export APPLE_SIGNING_IDENTITY='Developer ID Application: YOUR NAME (TEAMID)' +export APPLE_NOTARY_PROFILE='your-notary-profile' +``` + +For distribution, set both `macos.sign` / `macos.notarize` to `true`. +Alternatively, prefix the STEP5 macOS command with `NEXT2D_STEAM_RELEASE=1` to require both even when JSON specifies false. +Missing credentials, signing failures or notarization failures fail the build. +Signing failures stop before notarization. If the output shows `Signature=adhoc` / `TeamIdentifier=not set`, +the app lacks a Developer ID signature; check the preceding signing error and the certificate/private key in the keychain. + +Steam uses the `darwin` target. Valve requires 64-bit support and Apple notarization for new macOS applications. +The template entitlements include library validation / DYLD settings for JIT and Steam Overlay, +without `com.apple.security.app-sandbox` (which is separate from Chromium's renderer sandbox). +[Valve platform requirements](https://partner.steamgames.com/doc/store/application/platforms) / +[Electron Packager signing and notarization options](https://electron.github.io/packager/main/interfaces/Options.html) + +#### SteamCMD and the build account + +Obtain SteamCMD for your host OS from the [Steamworks SDK ContentBuilder](https://partner.steamgames.com/doc/sdk/uploading). +Use `steamcmd.exe` on Windows or `steamcmd.sh` on macOS / Linux. +The builder uses `steamcmd` on PATH (`steamcmd.exe` on Windows), or the executable path set in `STEAMCMD`. +Specify only the path, without arguments or a shell command. A `.sh` file needs executable permission. +Install any OS libraries required by SteamCMD according to its setup instructions. + +Grant the upload account `Edit App Metadata` and `Publish App Changes To Steam` permissions for the target app. +Example for macOS / Linux; replace the path and account name: + +```sh +export STEAMCMD="/absolute/path/to/steamcmd.sh" +export STEAM_USERNAME="your_build_account" +"$STEAMCMD" +login "$STEAM_USERNAME" +quit +``` + +During the first login, enter the password and, if requested, the Steam Guard code interactively in SteamCMD. +After login succeeds, wait for `+quit` to exit normally and confirm that the regular terminal prompt has returned. +If you log in manually at the `Steam>` prompt, also enter `quit` before proceeding to upload. +The builder then reuses the saved login for the same SteamCMD installation and account without passing a password as a command-line argument. +Logging into the Steam desktop app alone does not confirm that this SteamCMD authentication setup is complete. + +If uploading reports `Cached credentials not found` / `No cached credentials and @NoPromptForPassword is set`, or authentication expires, +rerun `"$STEAMCMD" +login "$STEAM_USERNAME" +quit` above, wait for it to exit normally, then retry the upload. +Builder uploads fail instead of waiting for interactive input, so retrying the builder alone cannot register login credentials. +In CI, restore and manage SteamCMD's `config/config.vdf` as a Secret and exclude it from build artifacts. +In Windows PowerShell, set `$env:STEAMCMD` and `$env:STEAM_USERNAME`. + +### STEP5: Export each OS and collect the packages + +Run the required OS commands from the game root. Exporting does not upload or publish anything. + +```sh +npx @next2d/builder --platform steam:windows --env prd +npx @next2d/builder --platform steam:macos --env prd +npx @next2d/builder --platform steam:linux --env prd +``` + +Append an option such as `--arch arm64` to change the architecture. +Template scripts `npm run build:steam:windows` / `build:steam:macos` / `build:steam:linux` perform the same operations +and already specify `--env prd`. Pass npm arguments with `-- --arch arm64` or `-- --env dev`. + +The default output location is `dist/steam//build//`. + +| OS | Entire folder to distribute | Separate depot Executable | Shared depot Executable | +|---|---|---|---| +| Windows | `My Game-win32-x64/` | `my-game.exe` | `windows/my-game.exe` | +| macOS | `My Game-darwin-universal/` | `My Game.app` | `macos/My Game.app` | +| Linux | `My Game-linux-x64/` | `my-game` | `linux/my-game` | + +Read the actual launch path, architecture and ContentRoot from `*-steampipe/launch.json`. +Distribute the entire folder, including Electron libraries, locales, licenses and resources. +Steam needs no DMG/DEB/MSI installer, and no additional application build is required after export. + +For separate machines or CI, collect each OS's `build//`, including `steam-package.json` and `*-steampipe/`, +under the same `dist/steam//build//` layout. Transfer CI artifacts as `tar.gz` to preserve macOS symlinks +and Linux executable permissions. Use STEP6's `--steam-root` for a custom output location. + +Re-export affected operating systems after changing configuration or version. Even with an unchanged version number, +keep all OS packages on the intended revision. When exporting x64 and arm64 successively for one OS, the last successful +architecture is used. Combining multiple architectures of one OS into a shared depot is not supported. + +Verify signing, notarization and stapling for macOS distribution packages (adjust the paths): + +```sh +codesign --verify --deep --strict --verbose=2 'dist/steam/macos/build/prd/My Game-darwin-universal/My Game.app' +echo $? +xcrun stapler validate 'dist/steam/macos/build/prd/My Game-darwin-universal/My Game.app' +echo $? +``` + +| Check | Successful output | Immediately following `echo $?` | +| --- | --- | --- | +| `codesign --verify --deep --strict --verbose=2` | The app path followed by `valid on disk` and `satisfies its Designated Requirement`. Additional results for nested code may also appear. | `0` | +| `xcrun stapler validate` | Ends with `The validate action worked!`. | `0` | + +Without `--verbose=2`, `codesign` normally prints nothing on success. An exit code of `0` indicates that verification passed. +Run `echo $?` immediately after each command you want to check. A nonzero exit code means verification failed; resolve the reported error and check again. +These commands verify the signature and the attached notarization ticket; they do not sign or notarize the app. +After both checks pass, still verify installation and launching through Steam in STEP6. + +Reference: [Apple's signature verification instructions](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html). + +### STEP6: Configure launching, upload and test + +Add OS-specific Launch Options in Steamworks under Installation > General Installation. +Use the Executable from STEP5's `launch.json`, leaving Arguments/Working Directory empty. +Set the 64-bit condition for x64. Match supported OS versions and minimum requirements to the bundled Electron and hardware testing, +then Publish the Steamworks changes. + +Run these commands from the game root. Shared and separate depots are uploaded together in a single AppBuild. +No Web/Electron rebuild or prior `--steam-manifest` command is needed. + +```sh +# Local validation only: no SteamCMD, credentials or Steam connection required +npx @next2d/builder --steam-upload --env prd --dry-run + +# After STEP4's SteamCMD login exits normally, upload to the configured branch in the same terminal +npx @next2d/builder --steam-upload --env prd +``` + +Use `--steam-comment` to set an optional upload comment. +It appears as the description under "Your Builds" in Steamworks (SteamPipe's `Desc`). + +```sh +npx @next2d/builder --steam-upload --env prd --steam-comment "Internal test: fix gamepad controls" +``` + +| Option / setting | Purpose | +|---|---| +| `--steam-branch internal` | Overrides `steam.branch`; requests activation through `SetLive`. `default` is not allowed. Switch public release builds through Steamworks. | +| `--steam-comment "Comment"` | Sets the upload comment. If omitted, keeps the existing ` (, )` format. Whitespace-only text, newlines, control characters, double quotes and backslashes are not allowed. Also shown in `--dry-run` output and `upload-plan.json`. | +| `--steam-root dist/steam` | Collected package location; defaults to `dist/steam`. Accepts an absolute path or a path relative to the game root. Specify custom output locations because uploading does not read the Vite configuration. | +| `--dry-run` | Validates packages against configuration. Does not check Steam permissions, branches or passwords. | +| Incompatible options | `--build` / `--preview` / `--open` / `--steam-manifest` / `--arch`. `--platform` is also unnecessary. | + +The corresponding template npm scripts are `upload:steam:check` / `upload:steam`. + +The builder checks `steam-package.json` and executables for every OS configured in `steam.depots`. +Missing or inconsistent App IDs, Depot IDs, versions, game names or architectures stop the operation before SteamCMD starts. +VDFs are regenerated from validated packages; ordinary export VDFs remain unchanged. + +| Location (under `--steam-root`) | Contents | +|---|---| +| `uploads//-/` | VDFs and `upload-plan.json`. Dry runs use `Preview=1` without `SetLive`. Successful uploads record the BuildID in `upload-result.json`. | +| `uploads//cache//` | SteamPipe logs and incremental upload cache. | + +On the Steamworks Builds page, verify that the recorded BuildID is the target branch's current build. +Steam may request additional confirmation depending on the account or app state. +Testers enter the password and select `internal` in the Steam client's Properties > Game Versions & Betas. +Verify installation and launch on each OS, including both Intel and Apple Silicon for macOS Universal. + +### Reference: VDF generation and manual uploading + +Skip these operations when using the builder in STEP6. This section is for direct SteamCMD use. + +| Layout | VDF output and conditions during ordinary export | +|---|---| +| Separate OS depots | Each OS's `*-steampipe/` directory. | +| Shared depots | `dist/steam/shared//depot-/` once all required OS packages exist. Missing operating systems are listed in `launch.json`; neither upload VDFs nor standalone per-OS VDFs are generated for an incomplete group. | + +Some operating systems may share a Depot ID while others use separate depots. `FileMapping` assigns OS subdirectories without copying assets again. +To regenerate only shared depot VDFs after collecting packages from separate machines: + +```sh +npx @next2d/builder --platform steam:macos --env prd --steam-manifest +``` + +The npm alias is `build:steam:manifest` (append `-- --env dev` for another environment). This command runs on any OS. +`--platform` selects the Vite configuration; all configured shared depots are combined. +It selects the last successful exports using `build.outDir` and `--env`, validating the App ID, Depot IDs, game name, executable name and version. +Missing packages cause exit code 1. Old combined VDFs are invalidated during regeneration. +Do not combine this command with `--arch` / `--preview` / `--build` / `--open`. + +`app_preview.vdf` validates file mappings, `app_build.vdf` uploads, and `depot_build.vdf` recursively maps folder contents. +`steam_appid.txt` is excluded from distribution. ContentRoot is relative to the VDF, so move a standalone depot's application +and `*-steampipe/` together; preserve the whole `dist/steam/` layout for shared depots. + +```text +steamcmd +login BUILD_ACCOUNT +run_app_build "/absolute/path/to/app_preview.vdf" +quit +steamcmd +login BUILD_ACCOUNT +run_app_build "/absolute/path/to/app_build.vdf" +quit +``` + +Ordinary exports and `--steam-manifest` omit `SetLive`; assign the uploaded build to its branch through Steamworks. +Each per-OS VDF updates one depot, so verify the final Build references the intended manifest version for every OS. +[Official SteamPipe workflow and VDF specification](https://partner.steamgames.com/doc/sdk/uploading) + +### Reference: Templates, host and migration + +`create-next2d-app` initializes `appId`, `appName`, `executableName` and `companyName` from the project name. +For example, `my-game` produces `app.example.my-game` for `appId` and `my-game` for the other three fields. +Replace the bundle ID and company name with your own values before distribution. +Missing CPU settings receive the defaults for each OS; values already provided by the template are preserved. +Other settings, such as icon paths and Steam IDs, are also preserved. + +The builder manages Electron host code. It stages the host, runtime configuration and web assets in an OS temporary directory, +then removes it after export, including failures. No `electron/`, Electron-specific `node_modules` or lockfile is created in the game. +Electron is pinned in `templates/electron/package.json`; Packager is pinned in `src/tool-packages.ts`. Both are downloaded and cached. +Packager is acquired only for Electron exports and handles OS packages, icons, signing and notarization. +The host has no npm dependencies or native addons, so ABI-specific rebuilding is unnecessary. +Preview exports for the host OS/CPU and launches the application under `dist//build//`. + +Legacy `electron/` host code, `config.forge` and custom npm dependencies are not used. +For migration, move icons into shared assets and update their JSON paths before deleting the old directory. +Custom main/preload code or native addons require builder support before migration. + +The template host loads assets using absolute paths and the fixed origin `next2d://game`. +Local fetch, Workers and localStorage work independently of the startup working directory. +F11/Alt+Enter enters fullscreen; Escape exits it. Closing the window also terminates the process on macOS. +Node integration is disabled, context isolation and sandboxing are enabled, and external navigation and new windows are blocked. +A Next2D CSP is applied. Games using external APIs must explicitly add their destinations. +[Electron security](https://www.electronjs.org/docs/latest/tutorial/security) / +[protocol](https://www.electronjs.org/docs/latest/api/protocol) + +Save data is stored in the `appId` directory under Electron's appData location. +Changing the display name does not change that location. Saves from older file-origin development builds are not migrated automatically. +Steam Cloud is not integrated. When adding it, design game-specific save files and per-account storage separately, +rather than syncing the entire Chromium profile. +[Steam Cloud](https://partner.steamgames.com/doc/features/cloud) + +### Pre-release validation + +In addition to STEP6's installation and launch checks, verify: + +- Exit behavior, offline launch and saved data after updates. +- Mouse/keyboard/controller input, resolution and fullscreen switching, audio and sleep/resume. +- Shift+Tab Overlay. Electron uses multiple processes, so verify actual behavior on each OS/GPU. + This export does not integrate the Steamworks SDK, achievements, DRM or Overlay APIs. + SDK integration is not required for Steam distribution. +- On Linux, check dependent libraries and sandboxing in the Steam Linux Runtime environment. + Do not use `--no-sandbox` as a distribution workaround. +- Steam Deck Verified requires a separate review. Producing a Linux package alone does not establish compatibility. + Test controller-only operation, text readability and display behavior on hardware. +- Before Steam's build review, verify that the supported operating systems and features advertised on the store match the application. + +[Steamworks API](https://partner.steamgames.com/doc/sdk/api) / +[Overlay](https://partner.steamgames.com/doc/features/overlay) / +[Linux development](https://partner.steamgames.com/doc/store/application/platforms/linux) / +[Steam Deck compatibility](https://partner.steamgames.com/doc/steamhardware/compat) / +[Build review](https://partner.steamgames.com/doc/store/review_process) diff --git a/docs/xbox.md b/docs/xbox.md new file mode 100644 index 0000000..5b9c16a --- /dev/null +++ b/docs/xbox.md @@ -0,0 +1,145 @@ +# Xbox(試作・開発段階 / Prototype under development) + +[日本語](#日本語) | [English](#english) + +## 日本語 + +Xbox対応はGDK向けネイティブホストの試作・開発段階。Xbox実機での動作確認・配布対応は完了していない。 +以下は開発環境での検証手順。 + +### STEP1:検証範囲に必要な環境を用意する + +| 検証範囲 | ユーザーが用意するもの | +|---|---| +| ホスト生成・アセット準備のみ | macOS / Linuxでも実行できる。 | +| C++ホストのビルド | Windows、Visual Studio 2022、Microsoft GDK、CMake 3.26以降。現行builderはVisual Studio 2022ジェネレーターを指定する。 | +| Xbox実機での検証 | コンソール向けGDK開発環境とXbox開発機(devkit)。PC向けのGDK検証環境とは区別して用意する。 | + +### STEP2:ゲーム設定とV8を用意する + +ゲームルートの `MicrosoftGame.config` にゲーム固有の値を設定する。 +未配置の場合は初回のホスト生成でテンプレートから作られるため、生成後に内容を確認・変更する。 + +V8はJavaScript実行エンジン。通常はbuilderがビルド済みライブラリを取得し、自前ビルドを使う場合だけパスを指定する。 +描画用のDawn(WebGPU → D3D12)はCMakeのFetchContentが取得するため、初回取得にはネットワーク接続が必要。 + +Windowsでのビルド時は、次の優先順でV8を解決する。 + +1. `--v8-root` で指定したパス +2. 環境変数 `V8_ROOT` +3. キャッシュ済みのビルド済みV8 +4. Next2D/builderのGitHub Releasesからダウンロード + +ビルド済みV8は `build-v8` ワークフローで作成・公開する構成になっている。 +取得対象のバージョンとリビジョンはbuilder側で固定し、取得後はキャッシュを再利用する。 +自前のV8を使用する場合: + +```bat +npx @next2d/builder --platform xbox --env prd --v8-root C:\path\to\v8 +``` + +公開しているWindows x64用V8の利用と、Xboxコンソール向けの互換性検証は別の作業。 +コンソール向けにはGDKツールチェーンでの調整・再ビルドを含む検証が残っている。 + +### STEP3:ホストを生成・ビルドする + +ゲームルートで実行する。 + +```sh +npx @next2d/builder --platform xbox --env prd +``` + +builder同梱のC++ / CMakeテンプレートから `xbox/` を生成・更新し、`MicrosoftGame.config` を反映する。 +Webビルド結果とホストスクリプトを `assets.pak` / `assets.rc` にまとめ、実行ファイルへの埋め込み用に配置する。 +このホストはV8とDawnを使い、ElectronやWebViewは使用しない。 + +| 実行環境・引数 | コマンドの到達点 | +|---|---| +| Windows | V8を解決し、CMakeでGDK向けの構成・ビルドを実行する。対象環境での検証が必要。 | +| Windows + `--open` / `--preview` | CMakeで構成した後、Visual Studioのソリューションを開く。実行・デバッグはVisual Studio側で行う。 | +| macOS / Linux | ホスト生成とアセット準備までで終了する。GDK向け実行ファイルは生成しない。 | + +### STEP4:生成物と対象環境での動作を確認する + +コマンドの終了だけでXbox向けの配布物が完成したとは判断せず、生成物とログを確認する。 + +`xbox-host-ci` ワークフローには、ラスタライザーとstbの回帰テスト、Windows APIを使う一部機能のテスト、 +V8依存ソースのコンパイル確認、Game Core APIの確認を用意している。 +これらはホスト全体のリンクやXbox実機での動作を保証するものではない。 +Dawn / GDKを含む統合ビルドと、ゲームを使った実機検証が必要。 + +今後の検証・調整対象は、描画、Worker、入力、音声、テキスト、保存処理、性能、配布設定など。 +詳細なホスト構成・自前V8のビルド・機能ごとの実装状況は、 +[ホストテンプレートの開発資料](../templates/xbox/README.md)を参照する。 +同じ資料は生成先の `xbox/README.md` にも配置される。 + +## English + +Xbox support is a prototype GDK native host under development. Xbox hardware validation and distribution support are not complete. +The following steps are for development testing. + +### STEP1: Prepare the environment for your validation scope + +| Validation scope | What you need to prepare | +|---|---| +| Host generation and asset preparation only | Also works on macOS / Linux. | +| Building the C++ host | Windows, Visual Studio 2022, Microsoft GDK and CMake 3.26 or later. The current builder selects the Visual Studio 2022 generator. | +| Testing on Xbox hardware | A console GDK development environment and Xbox development hardware (devkit), distinct from a PC GDK testing environment. | + +### STEP2: Prepare game configuration and V8 + +Set game-specific values in `MicrosoftGame.config` at the game root. +If absent, it is created from the template during initial host generation; review and edit it afterward. + +V8 is the JavaScript engine. The builder normally downloads a prebuilt library; specify a path only when using your own build. +CMake FetchContent acquires Dawn (WebGPU → D3D12) for rendering, so the first download requires network access. + +For Windows builds, V8 is resolved in this order: + +1. The path passed with `--v8-root` +2. The `V8_ROOT` environment variable +3. A cached prebuilt V8 +4. A download from the Next2D/builder GitHub Releases + +The `build-v8` workflow is configured to build and publish prebuilt V8 libraries. +The builder pins the download version and revision and reuses the cache after downloading. +To use your own V8 build: + +```bat +npx @next2d/builder --platform xbox --env prd --v8-root C:\path\to\v8 +``` + +Using the published Windows x64 V8 library and validating Xbox console compatibility are separate tasks. +Console support still needs validation, including adjustments or rebuilds with the GDK toolchain. + +### STEP3: Generate and build the host + +Run from the game root: + +```sh +npx @next2d/builder --platform xbox --env prd +``` + +The builder creates or updates `xbox/` from its bundled C++ / CMake templates and applies `MicrosoftGame.config`. +It packs the web build output and host scripts into `assets.pak` / `assets.rc` for embedding in the executable. +The host uses V8 and Dawn, without Electron or WebView. + +| Environment / options | What the command completes | +|---|---| +| Windows | Resolves V8, then configures and builds the GDK target with CMake. Target-environment validation is still needed. | +| Windows + `--open` / `--preview` | Opens the Visual Studio solution after CMake configuration. Run and debug from Visual Studio. | +| macOS / Linux | Stops after host generation and asset preparation; no GDK executable is built. | + +### STEP4: Check the output and target-environment behavior + +Command completion alone does not mean an Xbox distribution package is ready; inspect the output and logs. + +The `xbox-host-ci` workflow includes rasterizer and stb regression tests, tests for selected Windows API functionality, +compilation checks for V8-dependent sources and Game Core API checks. +These checks do not guarantee that the complete host links or runs on Xbox hardware. +An integrated build with Dawn / GDK and testing with a game on the target hardware are still required. + +Remaining validation and adjustments cover rendering, Workers, input, audio, text, save handling, performance and distribution settings. +For the detailed host architecture, instructions for building V8 yourself and implementation status by feature, +see the [host template development notes](../templates/xbox/README.md). +The same notes are copied to the generated `xbox/README.md`. diff --git a/package-lock.json b/package-lock.json index 5764177..3781578 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,620 +1,51 @@ { "name": "@next2d/builder", - "version": "0.1.11", + "version": "0.2.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@next2d/builder", - "version": "0.1.11", + "version": "0.2.0", "license": "MIT", - "dependencies": { - "@electron-forge/core": "^7.11.2", - "@types/node": "^26.4.0", - "picocolors": "^1.1.1", - "vite": "^8.2.2" - }, "bin": { "builder": "dist/index.js" }, "devDependencies": { "@eslint/eslintrc": "^3.3.7", "@eslint/js": "^10.0.1", - "@typescript-eslint/eslint-plugin": "^8.69.0", - "@typescript-eslint/parser": "^8.69.0", - "eslint": "^10.9.1", + "@types/node": "^26.6.2", + "@typescript-eslint/eslint-plugin": "^8.70.1", + "@typescript-eslint/parser": "^8.70.1", + "eslint": "^10.11.0", "eslint-plugin-unused-imports": "^4.4.1", "globals": "^17.12.0", - "typescript": "^6.0.3" - } - }, - "node_modules/@electron-forge/core": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/core/-/core-7.11.2.tgz", - "integrity": "sha512-RbOvlCahSlYBkY1XFgD5QuoifZltEY3ezYGqJYnV1z6RiUK1DfUXwdidmclBLI9d6u8NNr9xWPv79LHVc9ZA3Q==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/electron" - } - ], - "license": "MIT", - "dependencies": { - "@electron-forge/core-utils": "7.11.2", - "@electron-forge/maker-base": "7.11.2", - "@electron-forge/plugin-base": "7.11.2", - "@electron-forge/publisher-base": "7.11.2", - "@electron-forge/shared-types": "7.11.2", - "@electron-forge/template-base": "7.11.2", - "@electron-forge/template-vite": "7.11.2", - "@electron-forge/template-vite-typescript": "7.11.2", - "@electron-forge/template-webpack": "7.11.2", - "@electron-forge/template-webpack-typescript": "7.11.2", - "@electron-forge/tracer": "7.11.2", - "@electron/get": "^3.0.0", - "@electron/packager": "^18.3.5", - "@electron/rebuild": "^3.7.0", - "@malept/cross-spawn-promise": "^2.0.0", - "@vscode/sudo-prompt": "^9.3.1", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "eta": "^3.5.0", - "fast-glob": "^3.2.7", - "filenamify": "^4.1.0", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "global-dirs": "^3.0.0", - "got": "^11.8.5", - "interpret": "^3.1.1", - "jiti": "^2.4.2", - "listr2": "^7.0.2", - "log-symbols": "^4.0.0", - "node-fetch": "^2.6.7", - "rechoir": "^0.8.0", - "semver": "^7.2.1", - "source-map-support": "^0.5.13", - "username": "^5.1.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/core-utils": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/core-utils/-/core-utils-7.11.2.tgz", - "integrity": "sha512-/Fpwo44an6ulUdq94co5OOcbRCohgYNci/E6eoZZuTO9f72X+PqJkMkghqkMX3iQ8Aq2QRLkGKFwrKWJNTjL7Q==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "@electron/rebuild": "^3.7.0", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.3.1", - "find-up": "^5.0.0", - "fs-extra": "^10.0.0", - "log-symbols": "^4.0.0", - "parse-author": "^2.0.0", - "semver": "^7.2.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/maker-base": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/maker-base/-/maker-base-7.11.2.tgz", - "integrity": "sha512-9934zYu9WVdgCYQXvtS+eL1oyLagsY8JlWhZmoK8yWTYftSAydH7jb3seVpfy6n85SYmY/yjcAy2lvOTy5dUwA==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "fs-extra": "^10.0.0", - "which": "^2.0.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/plugin-base": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/plugin-base/-/plugin-base-7.11.2.tgz", - "integrity": "sha512-tIFzEE2+D9NnCAn/rLwSkh8H59IqN+G973JNl7xmCzquO6qa7/veitZOQFGO79Zmmgkc8R/fmiCbh7LIdLS9Tg==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/publisher-base": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/publisher-base/-/publisher-base-7.11.2.tgz", - "integrity": "sha512-YwK4ZF3+uW7PBEV/ho59NVTriP3fCahskORrztUaFIdG0QP3hqMsfmo01euv98FDsBEW9UXo7/EW8t5jpmYZ0Q==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/shared-types": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/shared-types/-/shared-types-7.11.2.tgz", - "integrity": "sha512-Tcles7y74xy3jN5dEC+Pt1duJYk4c7W2xu98tjWW8RewmfKD2uHkie6I1I3yifPFZXZ/QfTlaFOOoKIQ9ENZjg==", - "license": "MIT", - "dependencies": { - "@electron-forge/tracer": "7.11.2", - "@electron/packager": "^18.3.5", - "@electron/rebuild": "^3.7.0", - "listr2": "^7.0.2" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-base": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/template-base/-/template-base-7.11.2.tgz", - "integrity": "sha512-l10I+XZRbbxFGiDLMnuXmlOppmLYmimKj6FWjEGUvft4VJFXW2BIDrLIugIGdM1nbrl/0aYjen2xRg0nZlcWzg==", - "license": "MIT", - "dependencies": { - "@electron-forge/core-utils": "7.11.2", - "@electron-forge/shared-types": "7.11.2", - "@malept/cross-spawn-promise": "^2.0.0", - "debug": "^4.3.1", - "fs-extra": "^10.0.0", - "semver": "^7.2.1", - "username": "^5.1.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-vite": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite/-/template-vite-7.11.2.tgz", - "integrity": "sha512-yFSDSu3IdyNpgLXzrwODSUyaWniHRSZI82gwcXdnJLx7D7DIDLtbx6KzEoy7QBmWZRULO3F7rLsYG+Ur7orvyA==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "@electron-forge/template-base": "7.11.2", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-vite-typescript": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/template-vite-typescript/-/template-vite-typescript-7.11.2.tgz", - "integrity": "sha512-QvvdmO9Gdv+3aISI9+bBLKPBTyKaucs6HhXxz+IDALcdykIL9wVN0/BrWuwwgbwuw4BiJTyXGSPNXuJ+EWnP6g==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "@electron-forge/template-base": "7.11.2", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-webpack": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack/-/template-webpack-7.11.2.tgz", - "integrity": "sha512-JjG8XIZctrSZvTlii7Hqvt/pHDKigRk4PoLTQCs1TiT05ZWsn40itBm8cbja3L7bfm0ccDd3JTWWOl2G7PhlmA==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "@electron-forge/template-base": "7.11.2", - "fs-extra": "^10.0.0" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-webpack-typescript": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/template-webpack-typescript/-/template-webpack-typescript-7.11.2.tgz", - "integrity": "sha512-2lwK+OrCeZgYM8WqsUXJzk94rdF0z/kA7WnAf79U3COEmAAMcFIwJtwF8c/n+52UecP3yrEE70LIGmM1sjGZJQ==", - "license": "MIT", - "dependencies": { - "@electron-forge/shared-types": "7.11.2", - "@electron-forge/template-base": "7.11.2", - "fs-extra": "^10.0.0", - "typescript": "~5.4.5", - "webpack": "^5.69.1" - }, - "engines": { - "node": ">= 16.4.0" - } - }, - "node_modules/@electron-forge/template-webpack-typescript/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==", - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@electron-forge/tracer": { - "version": "7.11.2", - "resolved": "https://registry.npmjs.org/@electron-forge/tracer/-/tracer-7.11.2.tgz", - "integrity": "sha512-U8j5Hyj2Zt7I5PciJvPJfmEv69Gb/Da9v+k655z3Jj1cuY0UnToEJ61IhXrzlTYqo+jUKC+fgAjDJ6vltJTS0A==", - "license": "MIT", - "dependencies": { - "chrome-trace-event": "^1.0.3" - }, - "engines": { - "node": ">= 14.17.5" - } - }, - "node_modules/@electron/asar": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.4.1.tgz", - "integrity": "sha512-i4/rNPRS84t0vSRa2HorerGRXWyF4vThfHesw0dmcWHp+cspK743UanA0suA5Q5y8kzY2y6YKrvbIUn69BCAiA==", - "license": "MIT", - "dependencies": { - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/@electron/get": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-3.1.0.tgz", - "integrity": "sha512-F+nKc0xW+kVbBRhFzaMgPy3KwmuNTYX1fx6+FxxoSnNgwYX6LD7AKBTWkU0MQ6IBoe7dz069CNkR673sPAgkCQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=14" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/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==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/@electron/get/node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "license": "MIT", - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "typescript": "^6.0.3", + "vite": "^8.3.0" } }, - "node_modules/@electron/get/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==", - "license": "MIT", - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/@electron/node-gyp": { - "version": "10.2.0-electron.1", - "resolved": "git+ssh://git@github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "integrity": "sha512-CrYo6TntjpoMO1SHjl5Pa/JoUsECNqNdB7Kx49WLQpWzPw53eEITJ2Hs9fh/ryUYDn4pxZz11StaBYBrLFJdqg==", - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.0", - "exponential-backoff": "^3.1.1", - "glob": "^8.1.0", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.2.1", - "nopt": "^6.0.0", - "proc-log": "^2.0.1", - "semver": "^7.3.5", - "tar": "^6.2.1", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/node-gyp/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "node_modules/@cacheable/memory": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.2.0.tgz", + "integrity": "sha512-CTLKqLItRCEixEAewD3/j9DB3/o96gpTPD4eJ1v+DGOlxZRZncRQkGYqqnAGCscYd6RNeXfGeiuCphsPtqyIfQ==", + "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/node-gyp/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/node-gyp/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" + "@cacheable/utils": "^2.5.0", + "@keyv/bigmap": "^1.3.1", + "hookified": "^1.15.1", + "keyv": "^5.6.0" } }, - "node_modules/@electron/notarize": { + "node_modules/@cacheable/utils": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-2.5.0.tgz", - "integrity": "sha512-jNT8nwH1f9X5GEITXaQ8IF/KdskvIkOFfB2CvwumsveVidzpSc+mvhhTMdAGSYF3O+Nq49lJ7y+ssODRXu06+A==", - "license": "MIT", - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1", - "promise-retry": "^2.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "license": "MIT", - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/osx-sign": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.3.3.tgz", - "integrity": "sha512-KZ8mhXvWv2rIEgMbWZ4y33bDHyUKMXnx4M0sTyPNK/vcB81ImdeY9Ggdqy0SWbMDgmbqyQ+phgejh6V3R2QuSg==", - "license": "BSD-2-Clause", - "dependencies": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/packager": { - "version": "18.4.4", - "resolved": "https://registry.npmjs.org/@electron/packager/-/packager-18.4.4.tgz", - "integrity": "sha512-fTUCmgL25WXTcFpM1M72VmFP8w3E4d+KNzWxmTDRpvwkfn/S206MAtM2cy0GF78KS9AwASMOUmlOIzCHeNxcGQ==", - "license": "BSD-2-Clause", - "dependencies": { - "@electron/asar": "^3.2.13", - "@electron/get": "^3.0.0", - "@electron/notarize": "^2.1.0", - "@electron/osx-sign": "^1.0.5", - "@electron/universal": "^2.0.1", - "@electron/windows-sign": "^1.0.0", - "@malept/cross-spawn-promise": "^2.0.0", - "debug": "^4.0.1", - "extract-zip": "^2.0.0", - "filenamify": "^4.1.0", - "fs-extra": "^11.1.0", - "galactus": "^1.0.0", - "get-package-info": "^1.0.0", - "junk": "^3.1.0", - "parse-author": "^2.0.0", - "plist": "^3.0.0", - "prettier": "^3.4.2", - "resedit": "^2.0.0", - "resolve": "^1.1.6", - "semver": "^7.1.3", - "yargs-parser": "^21.1.1" - }, - "bin": { - "electron-packager": "bin/electron-packager.js" - }, - "engines": { - "node": ">= 16.13.0" - }, - "funding": { - "url": "https://github.com/electron/packager?sponsor=1" - } - }, - "node_modules/@electron/packager/node_modules/fs-extra": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", - "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/rebuild": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.7.2.tgz", - "integrity": "sha512-19/KbIR/DAxbsCkiaGMXIdPnMCJLkcf8AvGnduJtWBs/CBwiAjY1apCqOLVxrXg+rtXFCngbXhBanWjxLUt1Mg==", - "license": "MIT", - "dependencies": { - "@electron/node-gyp": "git+https://github.com/electron/node-gyp.git#06b29aafb7708acef8b3669835c8a7857ebc92d2", - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "node-abi": "^3.45.0", - "node-api-version": "^0.2.0", - "ora": "^5.1.0", - "read-binary-file-arch": "^1.0.6", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/universal": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-2.0.3.tgz", - "integrity": "sha512-Wn9sPYIVFRFl5HmwMJkARCCf7rqK/EurkfQ/rJZ14mHP3iYTjZSIOSVonEAnhWeAXwtw7zOekGRlc6yTtZ0t+g==", - "license": "MIT", - "dependencies": { - "@electron/asar": "^3.3.1", - "@malept/cross-spawn-promise": "^2.0.0", - "debug": "^4.3.1", - "dir-compare": "^4.2.0", - "fs-extra": "^11.1.1", - "minimatch": "^9.0.3", - "plist": "^3.1.0" - }, - "engines": { - "node": ">=16.4" - } - }, - "node_modules/@electron/universal/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", - "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/universal/node_modules/minimatch": { - "version": "9.0.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", - "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^2.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/windows-sign": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@electron/windows-sign/-/windows-sign-1.2.2.tgz", - "integrity": "sha512-dfZeox66AvdPtb2lD8OsIIQh12Tp0GNCRUDfBHIKGpbmopZto2/A8nSpYYLoedPIHpqkeblZ/k8OV0Gy7PYuyQ==", - "license": "BSD-2-Clause", - "dependencies": { - "cross-dirname": "^0.1.0", - "debug": "^4.3.4", - "fs-extra": "^11.1.1", - "minimist": "^1.2.8", - "postject": "^1.0.0-alpha.6" - }, - "bin": { - "electron-windows-sign": "bin/electron-windows-sign.js" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/@electron/windows-sign/node_modules/fs-extra": { - "version": "11.4.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.4.0.tgz", - "integrity": "sha512-EQsFzMUJkCKGr1ePqlYADkIUmHW1s3ZXr5Yqy6wbGrfUCphpl2maM/kyOIRA2HpP3AaFQTZXD4ldjek+nccddA==", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.5.0.tgz", + "integrity": "sha512-buipgOVDkkPXNR5+xBpDw7Zk2n1EvU7qBJCNUcL7rhQ//kfpOXPAvQ511Os0vpLYJ1pZnvudNytkQt2hst3wqA==", + "dev": true, "license": "MIT", "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" + "hashery": "^1.5.1", + "keyv": "^5.6.0" } }, "node_modules/@eslint-community/eslint-utils": { @@ -672,9 +103,9 @@ } }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { @@ -795,9 +226,9 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.2.tgz", - "integrity": "sha512-+CNAzxglkrpNf/kKywqQfk74QjtceuOE7Qm+AF8miRvPF/wmmK5+OJOgVh3AVTT3RP2mH3+FOaxlE5v72owk0A==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.7.3.tgz", + "integrity": "sha512-IkO+/KEUvwbVpiURZg+P7zF74z5Jxe0UgJxVni+RtoHQ6IZieXaO02kmadomap/q+l6bc/jdPGGqTjhuZnuz1Q==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -808,12 +239,6 @@ "node": "^20.19.0 || ^22.13.0 || >=24" } }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "license": "MIT" - }, "node_modules/@humanfs/core": { "version": "0.19.2", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", @@ -880,151 +305,48 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "node_modules/@keyv/bigmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.1.tgz", + "integrity": "sha512-WbzE9sdmQtKy8vrNPa9BRnwZh5UF4s1KTmSK0KUVLo3eff5BlQNNWDnFOouNpKfPKDnms9xynJjsMYjMaT/aFQ==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "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", + "hashery": "^1.4.0", + "hookified": "^1.15.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.6.0" } }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", - "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "dev": true, "license": "MIT" }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@malept/cross-spawn-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "license": "Apache-2.0", - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 12.13.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==", - "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==", - "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==", - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "license": "ISC", - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "license": "MIT", - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, "node_modules/@oxc-project/types": { - "version": "0.147.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.147.0.tgz", - "integrity": "sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==", + "version": "0.150.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.150.0.tgz", + "integrity": "sha512-rDS5/31E9HfPl/CIzGrn0DOlvBbXFseQ5URJ9sYMfstbKLD/c6Gm9vmRzRGDdAXyOIL4zmO37lc9RIwYqVruZw==", + "dev": true, "license": "MIT", "funding": { - "url": "https://github.com/sponsors/Boshen" + "url": "https://github.com/sponsors/oxc-project" } }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.6.tgz", - "integrity": "sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.9.tgz", + "integrity": "sha512-tNISae1QEf/vkb3xkRcjV5SEdzPE97We5IVaa2Z8jSszQPZ8U60B/YCYpw4QI7VidYsBtKavczXf+DyDs9WGxw==", "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1035,12 +357,13 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.6.tgz", - "integrity": "sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.9.tgz", + "integrity": "sha512-YC8YsI30o606GTZi0VyzYlsDKFP8W61i/QzayHDkLbNEz/IShqAmTa+hsJRj13xTHA0H+6fk4b2UmGn+Q/cMlg==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1051,12 +374,13 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.6.tgz", - "integrity": "sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.9.tgz", + "integrity": "sha512-IwhlH3qK5urrY8hZiEgGkHKEFN901p/p2bjxCxJlr4GyNnF7wYpUvK+Y43uaRYuC4hpfjzbR3SJC3arX1jGvmw==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1067,12 +391,13 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.6.tgz", - "integrity": "sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.9.tgz", + "integrity": "sha512-XxpJfVzFh+jilRxIXUqcfYAYcunIc/XEzIizsOL1fcJee5Sf7H3mH8WlLmfHfluz5amqR88QQo9izKtmMlavAw==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1083,12 +408,13 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.6.tgz", - "integrity": "sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.9.tgz", + "integrity": "sha512-kSfvhmgeWyfkbT3p/1s5vSgboogoah2zkm9fX2zjg2hHxSV7T4KhMWRUUaRk4OXNqoD3QAUeRqLcs1aZOK4U1g==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1099,12 +425,13 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.6.tgz", - "integrity": "sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.9.tgz", + "integrity": "sha512-1RVzG17pxqbTfYLC352JlLt6kKLG+6Hr30n8DlIJqsnV5luUDd2Qdx9Ayw1Cabfyb1K9k0jXEZ7evxkRoT+uiw==", "cpu": [ "arm" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1115,12 +442,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.6.tgz", - "integrity": "sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.9.tgz", + "integrity": "sha512-BXqPvZ2drqVD+/Z8UpKwcs4Mp7grM+eGFku4CAEKrEtcbAsUpzREphK1sogCRZGreVPiMkiiBtw0n3TPteuqvw==", "cpu": [ "arm64" ], + "dev": true, "libc": [ "glibc" ], @@ -1134,12 +462,13 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.6.tgz", - "integrity": "sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.9.tgz", + "integrity": "sha512-11vWvo8YDwLzukt27J3aYDWU+gg2P7J+ZOmiJ0hkF5BXZDW7pVya7r40MXDy6ya0i9KamoENSVKIugvJNgFXIA==", "cpu": [ "arm64" ], + "dev": true, "libc": [ "musl" ], @@ -1153,12 +482,13 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.6.tgz", - "integrity": "sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.9.tgz", + "integrity": "sha512-a1tijMkdwsIARtc0F39ApURROkf3NwqinI6TOiSSWCTR7dT96dffNvMUtDHnq64wKNTIZOIlzKrFvvFUznJiyw==", "cpu": [ "ppc64" ], + "dev": true, "libc": [ "glibc" ], @@ -1172,12 +502,13 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.6.tgz", - "integrity": "sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.9.tgz", + "integrity": "sha512-x6SQNdAvv4c3hWqTMaWuawzMX9myaCs/yEmlGsxJzkdClnHW7FbrjQuSiRDhuSYzEYoEMhsaJy9qHG/XNemJPQ==", "cpu": [ "s390x" ], + "dev": true, "libc": [ "glibc" ], @@ -1191,12 +522,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.6.tgz", - "integrity": "sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.9.tgz", + "integrity": "sha512-9s0AZ8BFK5/n7B/TBoa2yJE3gI3KURrbXcPBlsAsvjU4VeJKgE90y1YtNxyEUIcHPQkg6/yfF3qihUrcM/Kf0Q==", "cpu": [ "x64" ], + "dev": true, "libc": [ "glibc" ], @@ -1210,12 +542,13 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.6.tgz", - "integrity": "sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.9.tgz", + "integrity": "sha512-P7VWAmV+WdJluH7ovnRGoiv2i8To7GAZ+kGzfGup635cyL7SyYl3lSUaA3Gp5THf0n/Co5EyEqb2zbqq+nMOHQ==", "cpu": [ "x64" ], + "dev": true, "libc": [ "musl" ], @@ -1229,12 +562,13 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.6.tgz", - "integrity": "sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.9.tgz", + "integrity": "sha512-1qixtsE4BK8h+yS3BfmZ09UhA7O/N4IACva6YBr7EBvCJraByTuRcgOTaiA62Tm0vey3UcKXLOaoGHtYmNGEVg==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1245,12 +579,13 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.6.tgz", - "integrity": "sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.9.tgz", + "integrity": "sha512-ok8IQjcEPs1AKZfuEUznVBrJw+gK4soq+bx8b1X2XoMqVClarc1q5JDmVtWXY1xfr6ZuHTAsPXHTgTrqKTZeww==", "cpu": [ "arm64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1261,12 +596,13 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.6.tgz", - "integrity": "sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==", + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.9.tgz", + "integrity": "sha512-Ip2mXoU0hM0boq3Rf+ekuT653OROSo6aSYcPT1VHE4q52KvyxgFkQgrgb/IEsxOuvQ2fZZbs8khJAyCEPM24/g==", "cpu": [ "x64" ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -1280,53 +616,9 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, "license": "MIT" }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "license": "MIT", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.1.tgz", - "integrity": "sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==", - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "license": "MIT", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/esrecurse": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/@types/esrecurse/-/esrecurse-4.3.1.tgz", @@ -1338,69 +630,38 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", - "license": "MIT" - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", + "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/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/node": { - "version": "26.4.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-26.4.0.tgz", - "integrity": "sha512-faiGnoIrLH/V8cibOMEAZ8pMw6oXqSukl29ra4mN8GdaB2ZewzeaLj+INpV5N+Z1eKWzY+IzaIZH2EIR6YZRNQ==", - "license": "MIT", - "dependencies": { - "undici-types": "~8.3.0" - } - }, - "node_modules/@types/responselike": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", - "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "version": "26.6.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-26.6.2.tgz", + "integrity": "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g==", + "dev": true, "license": "MIT", - "optional": true, "dependencies": { - "@types/node": "*" + "undici-types": "~8.9.0" } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.69.0.tgz", - "integrity": "sha512-t5jQTKPIgVW1PE6dR6H6Qz5gm8zjMlX5/2gRaOGd9eO6V7J+tQc6iWKukEe7dY8u9HyYasQ0yfF0/FSSTEO2gA==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.70.1.tgz", + "integrity": "sha512-nDNrUQ/4ruSNYbu749TRY7cfrzPtoLHEXSNBI8aaNY32LlZCajixqRf3FqcKC4p5Cam4VOHYx/t+i5+nKXvrqA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/type-utils": "8.69.0", - "@typescript-eslint/utils": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/type-utils": "8.70.1", + "@typescript-eslint/utils": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1413,15 +674,15 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.69.0", + "@typescript-eslint/parser": "^8.70.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.8.tgz", - "integrity": "sha512-YYNsSlXBjMk92SKnkwvB5LOVSa6OznlFUGcsvrFgNJbJCd0M1XKeFVRc8ZByeCqz32FivYNHJVooLmdqrmvp/Q==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.9.tgz", + "integrity": "sha512-brTTsvFRt5C1gGHtPst/281UjPD5t9fBqbgoMPlVWy11ZLTPfu7HxK4ZYqO9H7o/yC9rSTCI85EaQ4OoY12qYw==", "dev": true, "license": "MIT", "engines": { @@ -1429,16 +690,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.69.0.tgz", - "integrity": "sha512-l4b0DhWioGg6Gt2ebGlvfkFMOjRsauxtsnDRwUSRX1qHq3HdTfQHV8wW9zEXeciai6HfeaKOedQn2Zoofx3WBw==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.70.1.tgz", + "integrity": "sha512-nO974WLllwhSFWQXnMLj6nDGa8f0khKEz1JzpPJ1u7Vm/4X1X6ZHajpoknU4bb41vJyMB0HHVyS2GqdhWfIXZw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", "debug": "^4.4.3" }, "engines": { @@ -1454,14 +715,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.69.0.tgz", - "integrity": "sha512-yi4obFrHMmnsesWehHbkg9zMA7Jt8cXT+mKM08G999pH1yT6nqgsHx7MYm0uY1wAj8CqiBXYRJ7WAT0QdQHQXg==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.70.1.tgz", + "integrity": "sha512-62xOgboPfwc3/IgPSX/W6oQR3ZbF04194FPGUGH8HL8iLFHbt/456/8Ph1wLNUgVF+s94FlHoipBsz+v7+LMnA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.69.0", - "@typescript-eslint/types": "^8.69.0", + "@typescript-eslint/tsconfig-utils": "^8.70.1", + "@typescript-eslint/types": "^8.70.1", "debug": "^4.4.3" }, "engines": { @@ -1476,14 +737,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.69.0.tgz", - "integrity": "sha512-ewfspqWvSxKSOaplqAUNbaSFO0eB6w1EtQ+esfYFRm3614Ty4uNtExkcbgd6nWsXphbqKyf9ZYdbZdv2xEoWEQ==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.70.1.tgz", + "integrity": "sha512-Pa0EeSeAusQc1WbjQMac+YfenewYTBu0KjgYvkUKwhXaHUKbFog23Dm/rp0DX/6tyYOQ3Xl1a+3EcFNZynGHCw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0" + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1494,9 +755,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.69.0.tgz", - "integrity": "sha512-xNqK7YTDZsLniQMV/4rpFR8Z5JlqeRvVjuG1YgF/mdPVH84HSD19L8CczMA0qg2RfwEV231GHH3VnToJDo4MfQ==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.70.1.tgz", + "integrity": "sha512-jumze1fPI+sDOaM2TWGQdn39PDxTr7TZGeuyLkAbNyx2vtMT3uRnVKChN0hfht5V2TugphJzF6bYXvBcE09qqg==", "dev": true, "license": "MIT", "engines": { @@ -1511,15 +772,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.69.0.tgz", - "integrity": "sha512-ZfoJAVg3JZndQEpEl9petVlxau3lRuElc4HRMuAlLCf8to04/iHz692RUSNmXKDjEuJmIL+KZ2/BsOcBc16dsA==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.70.1.tgz", + "integrity": "sha512-7zKTnyvaVWqzLZHPFQtX1hVHqgkMC+WebPWakNCSyrQVbIP1AM0L0TlBZtACldIRb6PptI8Odk+jyZ5kP3B1VA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0", - "@typescript-eslint/utils": "8.69.0", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1", + "@typescript-eslint/utils": "8.70.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1536,9 +797,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.69.0.tgz", - "integrity": "sha512-K3VrubUPhlo9VDBS6QdI8YB5j7ClpqLRdefcz6PFrhnwicehBweqQ9Evhl4l+FYz0HdDmMqIiSX0aldGRYtDCA==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.70.1.tgz", + "integrity": "sha512-Dm1ypdhhrGCTyyehxElhgJ6kgk8MVCv5qXdoOVqPr1uqk42jX8KjrZqhROvdShczA8qrDoYiOWn1ykWlx2k81Q==", "dev": true, "license": "MIT", "engines": { @@ -1550,16 +811,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.69.0.tgz", - "integrity": "sha512-AdFkgqck3Vudb/kWnxlyafU/4aBhHrbQ9locP2N4psXTy5mOBg0SHJumnLvx7r6g1gV4DKvUFwV2nJZBoqOD8w==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.70.1.tgz", + "integrity": "sha512-TU8PwyGN0PQJUcE96mw8eCQ44SmxGdQlJmlWakHaHQ15eIuuvye5yNtmh/i6oS88jzXVQB71xdNkbkB/fMwL0g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.69.0", - "@typescript-eslint/tsconfig-utils": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/visitor-keys": "8.69.0", + "@typescript-eslint/project-service": "8.70.1", + "@typescript-eslint/tsconfig-utils": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/visitor-keys": "8.70.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1588,9 +849,9 @@ } }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1617,16 +878,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.69.0.tgz", - "integrity": "sha512-tUbx60BBqQa31kXF5MCsOOLL5E/WzUuxIn7YpAvq+eaUlqvk8/NXnXMBNAdLCr0icjkzem7iUA5QqWHe/hJ1aw==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.70.1.tgz", + "integrity": "sha512-Esgul8MsnKnRLdYU2Eb2cRV9bS5HJYtKj1ByJnOzzG2M58DGdSUQ1jUuILxipqcpB2h9WLrbD5GijIWUjX/Tqw==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.69.0", - "@typescript-eslint/types": "8.69.0", - "@typescript-eslint/typescript-estree": "8.69.0" + "@typescript-eslint/scope-manager": "8.70.1", + "@typescript-eslint/types": "8.70.1", + "@typescript-eslint/typescript-estree": "8.70.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1641,13 +902,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.69.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.69.0.tgz", - "integrity": "sha512-+rmdgPA+EXkNgKYvHvFfhrs35utXbwaC5PGpDquSXcoXQDKUA5UjV0LmTucG/4JXkM31BTu4TilHtrN8IVBe8w==", + "version": "8.70.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.70.1.tgz", + "integrity": "sha512-Vwj9lUIW5Xq3wQ9w6gv3R86g1hMK8f2zNOdGTAgeXUMMXFK78G9ruCjjqutHMNJc0+CH7LYRnHeUB9IT8wFmcw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.69.0", + "@typescript-eslint/types": "8.70.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1671,189 +932,11 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@vscode/sudo-prompt": { - "version": "9.3.2", - "resolved": "https://registry.npmjs.org/@vscode/sudo-prompt/-/sudo-prompt-9.3.2.tgz", - "integrity": "sha512-gcXoCN00METUNFeQOFJ+C9xUI0DKB+0EGMVg7wbVYRHBw2Eq3fKisDZOkRdOz3kqXRKOENMfShPOmypw1/8nOw==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@xmldom/xmldom": { - "version": "0.9.12", - "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.9.12.tgz", - "integrity": "sha512-5AXjrcMClTryPe9LgZrygpB1lj7s0S9E0+W+AHaVKAVyHanafK86iPSvG5xHVSp/jC+VH1UXu0TAEmY279xH7A==", - "license": "MIT", - "engines": { - "node": ">=14.6" - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "license": "Apache-2.0" - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "license": "ISC" - }, "node_modules/acorn": { "version": "8.18.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.18.0.tgz", "integrity": "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ==", + "dev": true, "license": "MIT", "bin": { "acorn": "bin/acorn" @@ -1872,43 +955,6 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz", - "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==", - "license": "MIT", - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "license": "MIT", - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.15.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", @@ -1926,4045 +972,1014 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "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/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/brace-expansion": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.21.tgz", + "integrity": "sha512-9zeA+KLZNNzglF2TPKRQEDyx6Yby7daAkuy8MiPzpXPsYDWi/DRM8jmwUDxokQjYqBpv5DgPiwD4h4ZZSy1Ujw==", + "dev": true, "license": "MIT", "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "node_modules/cacheable": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.5.0.tgz", + "integrity": "sha512-60cyAOytib/OzBw1JNSoSV/boK1AtHryDIjvVBk7XbN4ugfkM3+Sry7fEjNgPMGgOjuaZPAp8ruZ0Cxafwyq9g==", + "dev": true, "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "@cacheable/memory": "^2.2.0", + "@cacheable/utils": "^2.5.0", + "hookified": "^1.15.0", + "keyv": "^5.6.0", + "qified": "^0.10.1" } }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/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/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/ansi-escapes": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", - "integrity": "sha512-5GFMVX8HqE/TB+FuBJGuO5XG0WrsA6ptUqoODaT/n9mmUaZFkqnBueB4leqGBCmrUHnCnC4PCZTCd0E7QQ83bA==", + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, "license": "MIT", "dependencies": { - "type-fest": "^1.0.2" + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 8" } }, - "node_modules/ansi-regex": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.3.0.tgz", - "integrity": "sha512-WpDfL7NO6j7tH88IDBNVdUJxDh9nmCteAVW9dsep846XdwF4naCBK+/tGLX3KJgcpgMRXCFlTM2hKGoK9FsdrQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "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==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, "license": "MIT", "dependencies": { - "color-convert": "^2.0.1" + "ms": "^2.1.3" }, "engines": { - "node": ">=8" + "node": ">=6.0" }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "node_modules/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": "Python-2.0" + "license": "MIT" }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "license": "ISC", + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">= 4.0.0" + "node": ">=8" } }, - "node_modules/author-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/author-regex/-/author-regex-1.0.0.tgz", - "integrity": "sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==", + "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": ">=0.8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "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/eslint": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.11.0.tgz", + "integrity": "sha512-P7a6UEEqb9G95MYAtqkmsTbVXIYyzIfl6NGOIJk162PaahFxFyeGcrlXYFSiagECg4sEm8IseJdZBKR3rx6MsQ==", + "dev": true, + "license": "MIT", + "workspaces": [ + "packages/*" ], - "license": "MIT" - }, - "node_modules/baseline-browser-mapping": { - "version": "2.11.20", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.11.20.tgz", - "integrity": "sha512-H0ulySigv6icDJ1F7SjtdCD6PrhTpdYCmP0CactWy1+ekh0AFd0o1Wn5T8b+hnTmdBx19u9yhL6wvCylXMY7zw==", - "license": "Apache-2.0", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.2", + "@eslint/config-array": "^0.23.5", + "@eslint/config-helpers": "^0.7.0", + "@eslint/core": "^1.2.1", + "@eslint/plugin-kit": "^0.7.3", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^9.1.2", + "eslint-visitor-keys": "^5.0.1", + "espree": "^11.2.0", + "esquery": "^1.7.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "11.1.5 || >11.1.6 <12", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "minimatch": "^10.2.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, "bin": { - "baseline-browser-mapping": "dist/cli.cjs" + "eslint": "bin/eslint.js" }, "engines": { - "node": ">=6.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } } }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "node_modules/eslint-plugin-unused-imports": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", + "integrity": "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==", + "dev": true, "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", + "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "license": "MIT" - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT", - "optional": true - }, - "node_modules/brace-expansion": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", - "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", - "license": "MIT", + "node_modules/eslint-scope": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", + "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "@types/esrecurse": "^4.3.1", + "@types/estree": "^1.0.8", + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, + "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": ">=8" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/browserslist": { - "version": "4.28.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.8.tgz", - "integrity": "sha512-V2NpofLblG64mfOtSgDhOJESZEGogzDMBv/q+W6oc4LXWP/q75eOXoOaaOu1EOadB9U4Bwx/e0yzbvwKH8zalA==", - "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" - } - ], + "node_modules/eslint/node_modules/balanced-match": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.11.12", - "caniuse-lite": "^1.0.30001809", - "electron-to-chromium": "^1.5.402", - "node-releases": "^2.0.53", - "update-browserslist-db": "^1.3.0" - }, - "bin": { - "browserslist": "cli.js" - }, "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + "node": "18 || 20 || >=22" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "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/eslint/node_modules/brace-expansion": { + "version": "5.0.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.12.tgz", + "integrity": "sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==", + "dev": true, "license": "MIT", "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "20 || >=22" } }, - "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==", - "license": "MIT", + "node_modules/eslint/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": "*" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "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==", - "license": "MIT" - }, - "node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "license": "ISC", + "node_modules/eslint/node_modules/espree": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", + "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" + "acorn": "^8.16.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^5.0.1" }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/cacache/node_modules/brace-expansion": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", - "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "license": "ISC", + "node_modules/eslint/node_modules/minimatch": { + "version": "10.2.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", + "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", + "dev": true, + "license": "BlueOak-1.0.0", "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" + "brace-expansion": "^5.0.8" }, "engines": { - "node": ">=12" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/cacache/node_modules/minimatch": { - "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", - "license": "ISC", + "node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "brace-expansion": "^2.0.1" + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" }, "engines": { - "node": ">=10" - } - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "license": "MIT", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", - "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", - "license": "MIT", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "node_modules/espree/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", "dev": true, - "license": "MIT", + "license": "Apache-2.0", "engines": { - "node": ">=6" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/caniuse-lite": { - "version": "1.0.30001810", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001810.tgz", - "integrity": "sha512-TITQPUkaz+aVk5GL6NhOdwk1aEaNTSDPsGFWrTuhKGtjTF70jL/Oht2W4c6rXUe5fu7Ie19VIahAXHIIiWWNeg==", - "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", + "node_modules/esquery": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "estraverse": "^5.1.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "node": ">=0.10" } }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "license": "ISC", + "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": ">=10" + "node": ">=4.0" } }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "license": "MIT", + "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": ">=6.0" + "node": ">=4.0" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "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": ">=6" + "node": ">=0.10.0" } }, - "node_modules/cli-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", - "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "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-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/fdir": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", + "dev": true, "license": "MIT", - "dependencies": { - "restore-cursor": "^4.0.0" - }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=12.0.0" }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } } }, - "node_modules/cli-spinners": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", - "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "node_modules/file-entry-cache": { + "version": "11.1.5", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-11.1.5.tgz", + "integrity": "sha512-+PFTHITI08JIGhnNpGNI8T8inUpgZfk3GNEqfT9R2zZV2iFXg3CvqzSl/uEhs7TSGujYRELEANyDvS8Fj7+S7Q==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "dependencies": { + "flat-cache": "^6.1.23" } }, - "node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "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": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", - "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/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "node_modules/flat-cache": { + "version": "6.1.23", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-6.1.23.tgz", + "integrity": "sha512-f++BY9pTk+983xK1FLzlLpmM0i0z+jHmx3QESGkURMXujQZz1k5wzwX6hjnQ8goaD0B+sYnDK1yZ6MTyZfUaqA==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=8" + "dependencies": { + "cacheable": "^2.5.0", + "flatted": "^3.4.2", + "hookified": "^1.15.0" } }, - "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==", - "license": "MIT" + "node_modules/flatted": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", + "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", + "dev": true, + "license": "ISC" }, - "node_modules/cliui/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==", + "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" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "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==", - "license": "MIT", + "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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "is-glob": "^4.0.3" }, "engines": { - "node": ">=8" + "node": ">=10.13.0" } }, - "node_modules/cliui/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==", + "node_modules/globals": { + "version": "17.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", + "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", + "dev": true, "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/hashery": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/hashery/-/hashery-1.5.1.tgz", + "integrity": "sha512-iZyKG96/JwPz1N55vj2Ie2vXbhu440zfUfJvSwEqEbeLluk7NnapfGqa7LH0mOsnDxTF85Mx8/dyR6HfqcbmbQ==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "hookified": "^1.15.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=20" } }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "node_modules/hookified": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-1.15.1.tgz", + "integrity": "sha512-MvG/clsADq1GPM2KGo2nyfaWVyn9naPiXrqIe4jYjXNZQt238kWyOGrsyc/DmRAQ+Re6yeo6yX/yoNCG5KAEVg==", + "dev": true, + "license": "MIT" + }, + "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": ">=0.8" + "node": ">= 4" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, "license": "MIT", "dependencies": { - "mimic-response": "^1.0.0" + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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", - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=0.8.19" } }, - "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/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "license": "MIT" - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "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": ">= 6" + "node": ">=0.10.0" } }, - "node_modules/compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "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/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" }, - "node_modules/cross-dirname": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cross-dirname/-/cross-dirname-0.1.0.tgz", - "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", - "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "clone": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "license": "MIT", - "engines": { - "node": ">=10" - } - }, - "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", - "optional": true, - "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==", - "license": "MIT", - "optional": true, - "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/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "license": "MIT", - "optional": true - }, - "node_modules/dir-compare": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-4.2.0.tgz", - "integrity": "sha512-2xMCmOoMrdQIPHdsTawECdNPwlVFB9zGcz3kuhmBO6U3oU+UQjsue0i8ayLKpgBcm+hcXPMVSGUN9d+pvJ6+VQ==", - "license": "MIT", - "dependencies": { - "minimatch": "^3.0.5", - "p-limit": "^3.1.0 " - } - }, - "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/electron-to-chromium": { - "version": "1.5.418", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.418.tgz", - "integrity": "sha512-UzS26r3AEbG5wSoGVpJKqwHIU9zwQN7LHdVIThDrJpS0I5KdlXFMEb8543fhc9dVnIIAST6ar8rhwa00AL5MlA==", - "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/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/end-of-stream": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "5.24.5", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.24.5.tgz", - "integrity": "sha512-L1l8TNvomm6UVW5B253AGxQagSQr+vGwhMlrrfRS2qmhx46AMpMVJKQYLvWYbysTMY8VoicOvzHzoHMbyzB+4A==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/error-ex": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "license": "MIT", - "optional": true, - "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-module-lexer": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.2.tgz", - "integrity": "sha512-poHGpORABojJJucnV9KbOavETW8lBVnphkW77ER5/BQ5Fz7oXSoCNek7IH3vR5nRjdsEz926ibFYX8KtLQmdyw==", - "license": "MIT" - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "license": "MIT", - "optional": true - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "devOptional": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "10.9.1", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-10.9.1.tgz", - "integrity": "sha512-9VaAkDURekixUQJy0oJYl2DcN6oKMfxay7XzaGYAWQwsb6qfKf+x76R2k1L8kb1boc+FyCAaTA9GmiKaaiaF+A==", - "dev": true, - "license": "MIT", - "workspaces": [ - "packages/*" - ], - "dependencies": { - "@eslint-community/eslint-utils": "^4.8.0", - "@eslint-community/regexpp": "^4.12.2", - "@eslint/config-array": "^0.23.5", - "@eslint/config-helpers": "^0.7.0", - "@eslint/core": "^1.2.1", - "@eslint/plugin-kit": "^0.7.2", - "@humanfs/node": "^0.16.6", - "@humanwhocodes/module-importer": "^1.0.1", - "@humanwhocodes/retry": "^0.4.2", - "@types/estree": "^1.0.6", - "ajv": "^6.14.0", - "cross-spawn": "^7.0.6", - "debug": "^4.3.2", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^9.1.2", - "eslint-visitor-keys": "^5.0.1", - "espree": "^11.2.0", - "esquery": "^1.7.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^8.0.0", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "minimatch": "^10.2.5", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://eslint.org/donate" - }, - "peerDependencies": { - "jiti": "*" - }, - "peerDependenciesMeta": { - "jiti": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-unused-imports": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-4.4.1.tgz", - "integrity": "sha512-oZGYUz1X3sRMGUB+0cZyK2VcvRX5lm/vB56PgNNcU+7ficUCKm66oZWKUubXWnOuPjQ8PvmXtCViXBMONPe7tQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^8.0.0-0 || ^7.0.0 || ^6.0.0 || ^5.0.0", - "eslint": "^10.0.0 || ^9.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } - } - }, - "node_modules/eslint-scope": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz", - "integrity": "sha512-xS90H51cKw0jltxmvmHy2Iai1LIqrfbw57b79w/J7MfvDfkIkFZ+kj6zC3BjtUwh150HsSSdxXZcsuv72miDFQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@types/esrecurse": "^4.3.1", - "@types/estree": "^1.0.8", - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "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/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/eslint/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/eslint/node_modules/eslint-visitor-keys": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/espree": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-11.2.0.tgz", - "integrity": "sha512-7p3DrVEIopW1B1avAGLuCSh1jubc01H2JHc8B4qqGblmg5gI9yumBgACjWo4JlIc04ufug4xJ3SQI8HkS/Rgzw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.16.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^5.0.1" - }, - "engines": { - "node": "^20.19.0 || ^22.13.0 || >=24" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.8" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", - "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", - "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/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/eta": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/eta/-/eta-3.5.0.tgz", - "integrity": "sha512-e3x3FBvGzeCIHhF+zhK8FZA2vC5uFn6b4HJjegUbIWrDb4mJ7JjTGMJY9VGIbRVpmSwHopNiaJibhjIr+HfLug==", - "license": "MIT", - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "url": "https://github.com/eta-dev/eta?sponsor=1" - } - }, - "node_modules/eventemitter3": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", - "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "license": "MIT", - "dependencies": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/cross-spawn": { - "version": "6.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.6.tgz", - "integrity": "sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==", - "license": "MIT", - "dependencies": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - }, - "engines": { - "node": ">=4.8" - } - }, - "node_modules/execa/node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/execa/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/execa/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/execa/node_modules/shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", - "license": "MIT", - "dependencies": { - "shebang-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/execa/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/exponential-backoff": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", - "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", - "license": "Apache-2.0" - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "license": "BSD-2-Clause", - "dependencies": { - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - }, - "bin": { - "extract-zip": "cli.js" - }, - "engines": { - "node": ">= 10.17.0" - }, - "optionalDependencies": { - "@types/yauzl": "^2.9.1" - } - }, - "node_modules/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==", - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "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.8" - }, - "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==", - "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/fast-uri": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.6.tgz", - "integrity": "sha512-7Ical1vFEMr0onbVzEDIreM22I4khW+fzyQPwvAFWBp1iwdshSZRsL4jjRvPG9JP1uiqMHRto+YU6R2/CzDz5Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastq": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.3.tgz", - "integrity": "sha512-XKv5nnLs6nLF71NgiKJLIZFLkPyIEuOselLG7ujZnGrRfQK8HpvY+WqKhAJUAdLomwVHErVS4LfxFlPq0/FTAw==", - "license": "ISC", - "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==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-entry-cache": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "flat-cache": "^4.0.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/filenamify": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-4.3.0.tgz", - "integrity": "sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg==", - "license": "MIT", - "dependencies": { - "filename-reserved-regex": "^2.0.0", - "strip-outer": "^1.0.1", - "trim-repeated": "^1.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "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==", - "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-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" - } - }, - "node_modules/flatted": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.4.tgz", - "integrity": "sha512-5+ybhBZANEJxaH3X5evAFatUxLfEHSr7n6kYJ+1Qd0mUqr4eu9gIf6GDbWHf8RJijHrjjO8G+la14SlL2SeS1Q==", - "dev": true, - "license": "ISC" - }, - "node_modules/flora-colossus": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/flora-colossus/-/flora-colossus-2.0.0.tgz", - "integrity": "sha512-dz4HxH6pOvbUzZpZ/yXhafjbR2I8cenK5xL0KtBFb7U2ADsR+OwXifnxZjij/pZWF775uSCMzWVd+jDik2H2IA==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "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==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "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==", - "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==", - "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/galactus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/galactus/-/galactus-1.0.0.tgz", - "integrity": "sha512-R1fam6D4CyKQGNlvJne4dkNF+PvUUl7TAJInvTGa9fti9qAv95quQz29GXapA4d8Ec266mJJxFVh82M4GIIGDQ==", - "license": "MIT", - "dependencies": { - "debug": "^4.3.4", - "flora-colossus": "^2.0.0", - "fs-extra": "^10.1.0" - }, - "engines": { - "node": ">= 12" - } - }, - "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==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-package-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-package-info/-/get-package-info-1.0.0.tgz", - "integrity": "sha512-SCbprXGAPdIhKAXiG+Mk6yeoFH61JlYunqdFQFHDtLjJlDjFf6x07dsS8acO+xWt52jpdVo49AlVDnUVK1sDNw==", - "license": "MIT", - "dependencies": { - "bluebird": "^3.1.1", - "debug": "^2.2.0", - "lodash.get": "^4.0.0", - "read-pkg-up": "^2.0.0" - }, - "engines": { - "node": ">= 4.0" - } - }, - "node_modules/get-package-info/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/get-package-info/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/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "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/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/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/global-dirs": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-3.0.1.tgz", - "integrity": "sha512-NBcGGFbBA9s1VzD41QXDG+3++t9Mn5t1FpLdhESY6oKY4gYTFpX4wO3sqGUa0Srjtbfj3szX0RnemmrVRUdULA==", - "license": "MIT", - "dependencies": { - "ini": "2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globals": { - "version": "17.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.12.0.tgz", - "integrity": "sha512-cezEd/DTyyht9cvSSURyygXPfy04GtWO/5e6ZPvH7fCtjKz9PYOmuawphw1Ctd1f6C+5JypXfGD7ahNMXvevBA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "define-properties": "^1.2.1", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "license": "MIT", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.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/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", - "optional": true, - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "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==", - "license": "ISC" - }, - "node_modules/http-cache-semantics": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", - "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", - "license": "BSD-2-Clause" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "license": "MIT", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "license": "MIT", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "license": "MIT", - "dependencies": { - "ms": "^2.0.0" - } - }, - "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/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "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/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "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/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "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==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "license": "ISC" - }, - "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.", - "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": "2.0.0", - "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", - "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ip-address": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.7.0.tgz", - "integrity": "sha512-BGFsyJd5mpXp3rK6jIdADLNgpJUK1jnjzvYF8lK+VyDab9JAmqN0YOKDdP17HlgKb2+ehPgDc8EtnRLbGCAMhA==", - "license": "MIT", - "engines": { - "node": ">= 12" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/is-core-module": { - "version": "2.16.2", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", - "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", - "license": "MIT", - "dependencies": { - "hasown": "^2.0.3" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-fullwidth-code-point": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", - "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "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==", - "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==", - "license": "MIT" - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "license": "MIT", - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC" - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/jiti": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.7.0.tgz", - "integrity": "sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==", - "license": "MIT", - "bin": { - "jiti": "lib/jiti-cli.mjs" - } - }, - "node_modules/js-yaml": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", - "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/puzrin" - }, - { - "type": "github", - "url": "https://github.com/sponsors/nodeca" - } - ], - "license": "MIT", - "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==", - "license": "MIT" - }, - "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-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "license": "ISC", - "optional": true - }, - "node_modules/jsonfile": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/junk": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/junk/-/junk-3.1.0.tgz", - "integrity": "sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "MIT", - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lightningcss": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", - "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", - "license": "MPL-2.0", - "dependencies": { - "detect-libc": "^2.0.3" - }, - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - }, - "optionalDependencies": { - "lightningcss-android-arm64": "1.33.0", - "lightningcss-darwin-arm64": "1.33.0", - "lightningcss-darwin-x64": "1.33.0", - "lightningcss-freebsd-x64": "1.33.0", - "lightningcss-linux-arm-gnueabihf": "1.33.0", - "lightningcss-linux-arm64-gnu": "1.33.0", - "lightningcss-linux-arm64-musl": "1.33.0", - "lightningcss-linux-x64-gnu": "1.33.0", - "lightningcss-linux-x64-musl": "1.33.0", - "lightningcss-win32-arm64-msvc": "1.33.0", - "lightningcss-win32-x64-msvc": "1.33.0" - } - }, - "node_modules/lightningcss-android-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", - "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-arm64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", - "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-darwin-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", - "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-freebsd-x64": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", - "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm-gnueabihf": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", - "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", - "cpu": [ - "arm" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", - "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", - "cpu": [ - "arm64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-arm64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", - "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", - "cpu": [ - "arm64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-gnu": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", - "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", - "cpu": [ - "x64" - ], - "libc": [ - "glibc" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-linux-x64-musl": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", - "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", - "cpu": [ - "x64" - ], - "libc": [ - "musl" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-arm64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", - "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", - "cpu": [ - "arm64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/lightningcss-win32-x64-msvc": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", - "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", - "cpu": [ - "x64" - ], - "license": "MPL-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/listr2": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-7.0.2.tgz", - "integrity": "sha512-rJysbR9GKIalhTbVL2tYbF2hVyDnrf7pFUZBwjPaMIdadYHmeT+EVi/Bu3qd7ETQPahTotg2WRCatXwRBW554g==", - "license": "MIT", - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.20", - "eventemitter3": "^5.0.1", - "log-update": "^5.0.1", - "rfdc": "^1.3.0", - "wrap-ansi": "^8.1.0" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha512-3p6ZOGNbiX4CdvEd1VcE6yi78UrGNpjHO33noGwHCnT/o2fyllJDepsm8+mFFv/DvtwFHht5HIHSyOy5a+ChVQ==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "deprecated": "This package is deprecated. Use the optional chaining (?.) operator instead.", - "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==", - "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/log-update": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-5.0.1.tgz", - "integrity": "sha512-5UtUDQ/6edw4ofyljDNcOVJQ4c7OjDro4h3y8e1GQL5iYElYclVHJ3zeWchylvMaKnDbDilC8irOVyexnA/Slw==", - "license": "MIT", - "dependencies": { - "ansi-escapes": "^5.0.0", - "cli-cursor": "^4.0.0", - "slice-ansi": "^5.0.0", - "strip-ansi": "^7.0.1", - "wrap-ansi": "^8.0.1" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "license": "ISC", - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "license": "MIT", - "dependencies": { - "p-defer": "^1.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "license": "MIT", - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "license": "MIT", - "dependencies": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "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==", - "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==", - "license": "MIT", - "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==", - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "license": "MIT", - "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==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimatch": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/minimizer-webpack-plugin": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.8.0.tgz", - "integrity": "sha512-2cT9+goJfBhtMz+gJqejSf09ClgmYhPhccRb/fb0ztVbixt0BkO8mRuI26FoPPuUNkRk6iEDryWAIouc5W8eJA==", - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.31", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.3", - "terser": "^5.51.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@minify-html/node": { - "optional": true - }, - "@swc/core": { - "optional": true - }, - "@swc/css": { - "optional": true - }, - "@swc/html": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "cssnano": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "html-minifier-terser": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "postcss": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/minipass": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", - "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "license": "MIT", - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.7.tgz", - "integrity": "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==", - "license": "BlueOak-1.0.0", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "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==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "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/nanoid": { - "version": "3.3.18", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.18.tgz", - "integrity": "sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==", - "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.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "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==", - "license": "MIT" - }, - "node_modules/nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "license": "MIT" - }, - "node_modules/node-abi": { - "version": "3.96.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.96.0.tgz", - "integrity": "sha512-rebQ/lz7i0EkoLzUVSrKRzA69zMkwLp95kKMWoMDkkM00Suxz0D7zEQPwRml5fQum24mj7bPvmlgLAmu2JCiYg==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-api-version": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.2.1.tgz", - "integrity": "sha512-2xP/IGGMmmSQpI1+O/k72jF/ykvZ89JeuKX3TLJAYPDVLUalrshrLHkeVcCCZqG/eEa635cr8IBYzgnDvM2O8Q==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - } - }, - "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==", - "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-releases": { - "version": "2.0.54", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.54.tgz", - "integrity": "sha512-YHs7BmmcsdAI5Ozuf8JZo6PT0mv2GIWC9vMfvUC3dp65M8hn7Ux8CPL+2oBI7juNuj9d0ndhTcznq2ODBps9cQ==", - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "license": "ISC", - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "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==", - "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/normalize-package-data/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "license": "ISC", - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", - "license": "MIT", - "dependencies": { - "path-key": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/npm-run-path/node_modules/path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.4" - } - }, - "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==", - "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==", - "license": "MIT", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "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==", - "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/ora/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/ora/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==", - "license": "MIT", - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/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==", - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ora/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/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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==", - "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==", - "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==", - "license": "MIT", - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-author": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-author/-/parse-author-2.0.0.tgz", - "integrity": "sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==", - "license": "MIT", - "dependencies": { - "author-regex": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==", - "license": "MIT", - "dependencies": { - "error-ex": "^1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "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==", - "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==", - "license": "MIT" - }, - "node_modules/path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha512-dUnb5dXUf+kzhC/W/F4e5/SkluXIFf5VUHolW1Eg1irn1hGWjPGdsRcvYJ1nD6lhk8Ir7VM0bHJKsYTx8Jx9OQ==", - "license": "MIT", - "dependencies": { - "pify": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/pe-library": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pe-library/-/pe-library-1.0.1.tgz", - "integrity": "sha512-nh39Mo1eGWmZS7y+mK/dQIqg7S1lp38DpRxkyoHf0ZcUs/HDc+yyTjuOtTvSMZHmfSLuSQaX945u05Y2Q6UWZg==", - "license": "MIT", - "engines": { - "node": ">=14", - "npm": ">=7" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/jet2jet" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz", - "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==", - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/plist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.1.1.tgz", - "integrity": "sha512-ZIfcLJC+7E7FBFnDxm9MPmt7D+DidyQ26lewieO75AdhA2ayMtsJSES0iWzqJQbcVRSrTufQoy0DR94xHue0oA==", - "license": "MIT", - "dependencies": { - "@xmldom/xmldom": "^0.9.10", - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=10.4.0" - } - }, - "node_modules/postcss": { - "version": "8.5.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.26.tgz", - "integrity": "sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==", - "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.17", - "picocolors": "^1.1.1", - "source-map-js": "^1.2.1" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postject": { - "version": "1.0.0-alpha.6", - "resolved": "https://registry.npmjs.org/postject/-/postject-1.0.0-alpha.6.tgz", - "integrity": "sha512-b9Eb8h2eVqNE8edvKdwqkrY6O7kAwmI8kcnBv1NScolYJbo59XUF0noFq+lxbC1yN20bmC0WBEbDC5H/7ASb0A==", - "license": "MIT", - "dependencies": { - "commander": "^9.4.0" - }, - "bin": { - "postject": "dist/cli.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/postject/node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "license": "MIT", - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "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.9.6", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", - "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", - "license": "MIT", - "bin": { - "prettier": "bin/prettier.cjs" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/proc-log": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-2.0.1.tgz", - "integrity": "sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw==", - "license": "ISC", - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "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==", - "license": "MIT", - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/pump": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "node_modules/js-yaml": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz", + "integrity": "sha512-SFNOvSJ+Dgf/9An904Yx+CgSlIPCkIpao4qo51lpee25TIRejdH3rhR4EZMGoNx3/TP3O+wzWuiTFl4sqbltzA==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "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" + "url": "https://github.com/sponsors/puzrin" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/nodeca" } ], - "license": "MIT" - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/read-binary-file-arch": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/read-binary-file-arch/-/read-binary-file-arch-1.0.6.tgz", - "integrity": "sha512-BNg9EN3DD3GsDXX7Aa8O4p92sryjkmzYYgmgTAc6CA4uGLEDzFfxOxugu21akOxpcXHiEgsYkC6nPsQvLLLmEg==", "license": "MIT", "dependencies": { - "debug": "^4.3.4" + "argparse": "^2.0.1" }, "bin": { - "read-binary-file-arch": "cli.js" + "js-yaml": "bin/js-yaml.js" } }, - "node_modules/read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha512-eFIBOPW7FGjzBuk3hdXEuNSiTZS/xEMlH49HxMyzb0hyPfu4EhVjT2DH32K1hSSmVq4sebAWnZuuY5auISUTGA==", - "license": "MIT", - "dependencies": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "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/read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha512-1orxQfbWGUiTn9XsPlChs6rLie/AV9jwZTGmu2NZw/CUDJQchXJFYE0Fq5j7+n558T1JhDWLdhyd1Zj+wLY//w==", - "license": "MIT", - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - }, - "engines": { - "node": ">=4" - } + "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/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==", + "node_modules/keyv": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.6.0.tgz", + "integrity": "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw==", + "dev": true, "license": "MIT", "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" + "@keyv/serialize": "^1.1.1" } }, - "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==", + "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": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" }, "engines": { - "node": ">=4" + "node": ">= 0.8.0" } }, - "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==", - "license": "MIT", + "node_modules/lightningcss": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.33.0.tgz", + "integrity": "sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==", + "dev": true, + "license": "MPL-2.0", "dependencies": { - "p-try": "^1.0.0" + "detect-libc": "^2.0.3" }, "engines": { - "node": ">=4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.33.0", + "lightningcss-darwin-arm64": "1.33.0", + "lightningcss-darwin-x64": "1.33.0", + "lightningcss-freebsd-x64": "1.33.0", + "lightningcss-linux-arm-gnueabihf": "1.33.0", + "lightningcss-linux-arm64-gnu": "1.33.0", + "lightningcss-linux-arm64-musl": "1.33.0", + "lightningcss-linux-x64-gnu": "1.33.0", + "lightningcss-linux-x64-musl": "1.33.0", + "lightningcss-win32-arm64-msvc": "1.33.0", + "lightningcss-win32-x64-msvc": "1.33.0" } }, - "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==", - "license": "MIT", - "dependencies": { - "p-limit": "^1.1.0" - }, + "node_modules/lightningcss-android-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.33.0.tgz", + "integrity": "sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], "engines": { - "node": ">=4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "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==", - "license": "MIT", + "node_modules/lightningcss-darwin-arm64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.33.0.tgz", + "integrity": "sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "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==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.33.0.tgz", + "integrity": "sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">= 6" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.33.0.tgz", + "integrity": "sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], "engines": { - "node": ">= 10.13.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "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==", - "license": "MIT", + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.33.0.tgz", + "integrity": "sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "license": "MIT", + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.33.0.tgz", + "integrity": "sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.10.0" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/resedit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/resedit/-/resedit-2.0.3.tgz", - "integrity": "sha512-oTeemxwoMuxxTYxXUwjkrOPfngTQehlv0/HoYFNkB4uzsP1Un1A9nI8JQKGOFkxpqkC7qkMs0lUsGrvUlbLNUA==", - "license": "MIT", - "dependencies": { - "pe-library": "^1.0.1" - }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.33.0.tgz", + "integrity": "sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=14", - "npm": ">=7" + "node": ">= 12.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/jet2jet" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/resolve": { - "version": "1.22.12", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", - "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.33.0.tgz", + "integrity": "sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">= 0.4" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "license": "MIT" - }, - "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==", + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.33.0.tgz", + "integrity": "sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "MIT", + "libc": [ + "musl" + ], + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=4" - } - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "license": "MIT", - "dependencies": { - "lowercase-keys": "^2.0.0" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/restore-cursor": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", - "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", - "license": "MIT", - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.33.0.tgz", + "integrity": "sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 12.0.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "license": "MIT", + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.33.0.tgz", + "integrity": "sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], "engines": { - "node": ">= 4" + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "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", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", - "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", - "license": "MIT" - }, - "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", - "license": "ISC", "dependencies": { - "glob": "^7.1.3" + "p-locate": "^5.0.0" }, - "bin": { - "rimraf": "bin.js" + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "license": "BSD-3-Clause", - "optional": true, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=8.0" + "node": "*" } }, - "node_modules/rolldown": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.6.tgz", - "integrity": "sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==", - "license": "MIT", - "dependencies": { - "@oxc-project/types": "=0.147.0", - "@rolldown/pluginutils": "^1.0.0" - }, - "bin": { - "rolldown": "bin/cli.mjs" - }, - "engines": { - "node": "^20.19.0 || >=22.12.0" - }, - "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.6", - "@rolldown/binding-android-arm64": "1.2.6", - "@rolldown/binding-darwin-arm64": "1.2.6", - "@rolldown/binding-darwin-x64": "1.2.6", - "@rolldown/binding-freebsd-x64": "1.2.6", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.6", - "@rolldown/binding-linux-arm64-gnu": "1.2.6", - "@rolldown/binding-linux-arm64-musl": "1.2.6", - "@rolldown/binding-linux-ppc64-gnu": "1.2.6", - "@rolldown/binding-linux-s390x-gnu": "1.2.6", - "@rolldown/binding-linux-x64-gnu": "1.2.6", - "@rolldown/binding-linux-x64-musl": "1.2.6", - "@rolldown/binding-openharmony-arm64": "1.2.6", - "@rolldown/binding-win32-arm64-msvc": "1.2.6", - "@rolldown/binding-win32-x64-msvc": "1.2.6" - } - }, - "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" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" }, - "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==", + "node_modules/nanoid": { + "version": "3.3.19", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.19.tgz", + "integrity": "sha512-Y2tUNy4ouw6tq5oDSKeQYGOyhkUBhNOcGV/02KC+6kd9eDGqdZd++mjMiIDilrBYvjEnCYvVtsuHCuP+okSfug==", + "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" + "url": "https://github.com/sponsors/ai" } ], - "license": "MIT" - }, - "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", - "optional": true - }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" + "bin": { + "nanoid": "bin/nanoid.cjs" }, "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.20.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", - "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "node_modules/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/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" + "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": ">=10" + "node": ">= 0.8.0" } }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "license": "MIT", - "optional": true - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "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", - "optional": true, "dependencies": { - "type-fest": "^0.13.1" + "yocto-queue": "^0.1.0" }, "engines": { "node": ">=10" @@ -5973,12 +1988,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "license": "(MIT OR CC0-1.0)", - "optional": true, + "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" }, @@ -5986,375 +2004,236 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "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": { - "shebang-regex": "^3.0.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "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==", + "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/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==", - "license": "ISC" - }, - "node_modules/slice-ansi": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", - "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, "license": "MIT", - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "node": ">=8" } }, - "node_modules/slice-ansi/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", + "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", + "dev": true, "license": "MIT", "engines": { "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", - "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", - "license": "MIT", - "dependencies": { - "ip-address": "^10.1.1", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "node_modules/postcss": { + "version": "8.5.28", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.28.tgz", + "integrity": "sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==", + "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": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" + "nanoid": "^3.3.18", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" }, "engines": { - "node": ">= 10" - } - }, - "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==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" + "node": "^10 || ^12 || >=14" } }, - "node_modules/source-map-js": { + "node_modules/prelude-ls": { "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==", - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.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==", - "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==", - "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==", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true, "license": "MIT", - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.23", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", - "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", - "license": "CC0-1.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==", - "license": "BSD-3-Clause", - "optional": true - }, - "node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "license": "ISC", - "dependencies": { - "minipass": "^3.1.1" - }, "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" + "node": ">= 0.8.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==", + "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", - "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": ">=6" } }, - "node_modules/strip-ansi": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", + "node_modules/qified": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz", + "integrity": "sha512-+Owyggi9IxT1ePKGafcI87ubSmxol6smwJ+RAHDQlx9+9cPwFWDiKFFCPuWhr9ignlGpZ9vDQLw67N4dcTVFEA==", + "dev": true, "license": "MIT", "dependencies": { - "ansi-regex": "^6.2.2" + "hookified": "^2.1.1" }, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": ">=4" + "node": ">=20" } }, - "node_modules/strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } + "node_modules/qified/node_modules/hookified": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/hookified/-/hookified-2.2.0.tgz", + "integrity": "sha512-p/LgFzRN5FeoD3DLS6bkUapeye6E4SI6yJs6KetENd18S+FBthqYq2amJUWpt5z0EQwwHemidjY5OqJGEKm5uA==", + "dev": true, + "license": "MIT" }, - "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==", + "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": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=4" } }, - "node_modules/strip-outer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.1.tgz", - "integrity": "sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg==", + "node_modules/rolldown": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.9.tgz", + "integrity": "sha512-hx/Pv0N1haXRb11qkfnK5MXB/iqr7i0yjWQqmO9uHqZpBgQSqzc8UsSnEpalsh+j1I8qQ2CkXAkJC8Br3dKSlg==", + "dev": true, "license": "MIT", "dependencies": { - "escape-string-regexp": "^1.0.2" + "@oxc-project/types": "=0.150.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" }, "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strip-outer/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==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm-eabi": "1.2.9", + "@rolldown/binding-android-arm64": "1.2.9", + "@rolldown/binding-darwin-arm64": "1.2.9", + "@rolldown/binding-darwin-x64": "1.2.9", + "@rolldown/binding-freebsd-x64": "1.2.9", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.9", + "@rolldown/binding-linux-arm64-gnu": "1.2.9", + "@rolldown/binding-linux-arm64-musl": "1.2.9", + "@rolldown/binding-linux-ppc64-gnu": "1.2.9", + "@rolldown/binding-linux-s390x-gnu": "1.2.9", + "@rolldown/binding-linux-x64-gnu": "1.2.9", + "@rolldown/binding-linux-x64-musl": "1.2.9", + "@rolldown/binding-openharmony-arm64": "1.2.9", + "@rolldown/binding-win32-arm64-msvc": "1.2.9", + "@rolldown/binding-win32-x64-msvc": "1.2.9" } }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.1.0" + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, "engines": { - "node": ">= 8.0" + "node": ">=10" } }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "shebang-regex": "^3.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==", - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", - "integrity": "sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" + "node": ">=8" } }, - "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==", - "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", - "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" - }, + "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": ">=10" + "node": ">=0.10.0" } }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", + "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" - } - }, - "node_modules/terser": { - "version": "5.51.2", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.51.2.tgz", - "integrity": "sha512-bWnjSNscmuI+GJze6ZupnHP8G/cTcsJF+bXCeQknk2SHQsgbNJnLrqiH9jZ2W4STPVXH2mDKKRX3iwPhc9Cn/Q==", - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, "node_modules/tinyglobby": { "version": "0.2.17", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -6367,74 +2246,6 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, - "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", - "license": "MIT", - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/tinyglobby/node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "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==", - "license": "MIT", - "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==", - "license": "MIT" - }, - "node_modules/trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg==", - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/trim-repeated/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==", - "license": "MIT", - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -6461,18 +2272,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", - "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/typescript": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", @@ -6488,74 +2287,12 @@ } }, "node_modules/undici-types": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.3.0.tgz", - "integrity": "sha512-j375ScV60dom+YkPFIfTLcOiPxkN/buHz5GobjLhixFuANaNs3C9l4GmrWqejgXWJ7BbJcFYpTEUkS1Ge8bpZQ==", + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-8.9.0.tgz", + "integrity": "sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==", + "dev": true, "license": "MIT" }, - "node_modules/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "license": "ISC", - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "license": "ISC", - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "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/update-browserslist-db": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.3.2.tgz", - "integrity": "sha512-UQ+MSxlhRm1bzjhU+DcuXfjFO1FzNtqhK5+9Yvlp90ItDLk5vT932A0rFu619nf7RVS+Y/VeaUW1jaRDqZ8VJw==", - "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.1" - }, - "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", @@ -6566,45 +2303,17 @@ "punycode": "^2.1.0" } }, - "node_modules/username": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/username/-/username-5.1.0.tgz", - "integrity": "sha512-PCKbdWw85JsYMvmCv5GH3kXmM66rCd9m1hBEDutPNv94b/pqCMT4NtcKyeWYvLFiE8b+ha1Jdl8XAaUdPn5QTg==", - "license": "MIT", - "dependencies": { - "execa": "^1.0.0", - "mem": "^4.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "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==", - "license": "Apache-2.0", - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, "node_modules/vite": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-8.2.2.tgz", - "integrity": "sha512-cFKLV/PRgAUlIRm5WjMjJ86jrftzpqcgH+Us+DS8mI3CDNiH30Whrz8uHL3+MOLPAgqbMBAqWdAHAphOAM+z/Q==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.3.0.tgz", + "integrity": "sha512-lhZBVvEHefgE+HQZC9O7EBJgCU/nVzFNl7vkS4RE0APtWLP02/8QVIkQtzBxPquh7lq5/78NHipTj7ODQ6XuyQ==", + "dev": true, "license": "MIT", "dependencies": { "lightningcss": "^1.33.0", - "picomatch": "^4.0.5", - "postcss": "^8.5.26", - "rolldown": "~1.2.4", + "picomatch": "^4.0.7", + "postcss": "^8.5.28", + "rolldown": "~1.2.6", "tinyglobby": "^0.2.17" }, "bin": { @@ -6621,7 +2330,7 @@ }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", - "@vitejs/devtools": "^0.4.0 || ^0.5.0", + "@vitejs/devtools": "^0.7.1", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", @@ -6672,110 +2381,11 @@ } } }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz", - "integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/watchpack": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz", - "integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==", - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", - "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/webpack": { - "version": "5.110.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.110.2.tgz", - "integrity": "sha512-TciLrfM7zgEjqGdY851HkirDsSPQgTFsWQpl9oHqMAMYsHhEC0bKjscvjpnz+pzx10hLC8qISApGrsnrCP4UtQ==", - "license": "MIT", - "dependencies": { - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.16.0", - "browserslist": "^4.28.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.24.4", - "es-module-lexer": "^2.1.0", - "events": "^3.2.0", - "graceful-fs": "^4.2.11", - "mime-db": "^1.54.0", - "minimizer-webpack-plugin": "^5.7.0", - "neo-async": "^2.6.2", - "schema-utils": "^4.3.3", - "tapable": "^2.3.0", - "watchpack": "^2.5.2", - "webpack-sources": "^3.5.1" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-sources": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.1.tgz", - "integrity": "sha512-jyuiGJdtvY434z5bUZrjz67v76/ePNvFZTp9Mdz29IlH4+GPsgyGjiv0fKI+M7BdkU6ADjulUcKAd3tUK3WlEw==", - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "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==", + "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -6797,156 +2407,11 @@ "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==", - "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/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?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==", - "license": "ISC" - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "license": "MIT", - "engines": { - "node": ">=8.0" - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "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==", - "license": "ISC" - }, - "node_modules/yargs": { - "version": "17.7.3", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", - "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", - "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==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs/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/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==", - "license": "MIT" - }, - "node_modules/yargs/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/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==", - "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/yargs/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/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, "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" diff --git a/package.json b/package.json index 7dc37af..85a7d58 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@next2d/builder", - "version": "0.1.11", + "version": "0.2.0", "description": "Multi-platform builder for Next2d Framework, supporting export to various platforms such as macOS, Windows, iOS, Android and Web(HTML)", "author": "Toshiyuki Ienaga ", "license": "MIT", @@ -29,7 +29,8 @@ }, "files": [ "dist", - "templates" + "templates", + "docs" ], "repository": { "type": "git", @@ -38,20 +39,16 @@ "bin": { "@next2d/builder": "dist/index.js" }, - "dependencies": { - "@electron-forge/core": "^7.11.2", - "@types/node": "^26.4.0", - "picocolors": "^1.1.1", - "vite": "^8.2.2" - }, "devDependencies": { "@eslint/eslintrc": "^3.3.7", "@eslint/js": "^10.0.1", - "@typescript-eslint/eslint-plugin": "^8.69.0", - "@typescript-eslint/parser": "^8.69.0", - "eslint": "^10.9.1", + "@types/node": "^26.6.2", + "@typescript-eslint/eslint-plugin": "^8.70.1", + "@typescript-eslint/parser": "^8.70.1", + "eslint": "^10.11.0", "eslint-plugin-unused-imports": "^4.4.1", "globals": "^17.12.0", - "typescript": "^6.0.3" + "typescript": "^6.0.3", + "vite": "^8.3.0" } } diff --git a/src/cli.ts b/src/cli.ts index c7d5c07..c856af8 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,5 +1,5 @@ // CLI 引数の解析とヘルプ表示。process.argv を読み取り ctx を初期化する。 -import pc from "picocolors"; +import pc from "./colors.js"; import { ctx } from "./context.js"; import { RECOMMENDED_NODE_VERSION } from "./constants.js"; @@ -26,6 +26,11 @@ export const echoHelp = (): void => console.log("For Xbox build example (prebuilt V8 is downloaded automatically):"); console.log("npx @next2d/builder --platform xbox --env prd"); console.log("To use your own V8 build: --v8-root C:\\path\\to\\v8"); + console.log("Steam: --platform steam:windows|steam:macos|steam:linux --env prd"); + console.log("Electron: --arch x64|arm64|universal (default: macOS universal, others x64)"); + console.log("Combine existing Steam packages only: --platform steam:macos --env prd --steam-manifest"); + console.log("Upload existing packages: --steam-upload --env prd [--steam-branch internal] [--steam-root dist/steam] [--steam-comment \"Build comment\"] [--dry-run]"); + console.log("Steam upload uses STEAM_USERNAME and optional STEAMCMD (executable path); no --platform is needed."); console.log(); process.exit(1); }; @@ -40,6 +45,13 @@ export interface ParsedArgs { open: boolean; build: boolean; v8Root: string; + arch: string; + steamManifest: boolean; + steamUpload: boolean; + steamBranch: string; + steamRoot: string; + steamComment: string; + dryRun: boolean; hasHelp: boolean; } @@ -72,6 +84,13 @@ export const parseArgv = (argv: string[]): ParsedArgs => "open": false, "build": false, "v8Root": "", + "arch": "", + "steamManifest": false, + "steamUpload": false, + "steamBranch": "", + "steamRoot": "", + "steamComment": "", + "dryRun": false, "hasHelp": false }; @@ -79,6 +98,36 @@ export const parseArgv = (argv: string[]): ParsedArgs => switch (argv[idx]) { + case "--steam-upload": + result.steamUpload = true; + break; + + case "--dry-run": + result.dryRun = true; + break; + + case "--steam-branch": + case "--steam-root": + case "--steam-comment": { + const flag = argv[idx]; + const value = argv[++idx] || ""; + if (!value || value.startsWith("--")) { + result.hasHelp = true; + } + if (flag === "--steam-branch") { + result.steamBranch = value; + } else if (flag === "--steam-root") { + result.steamRoot = value; + } else { + result.steamComment = value; + } + break; + } + + case "--steam-manifest": + result.steamManifest = true; + break; + case "--preview": result.preview = true; break; @@ -109,7 +158,17 @@ export const parseArgv = (argv: string[]): ParsedArgs => result.v8Root = argv[++idx] || ""; break; + case "--arch": + result.arch = argv[++idx] || ""; + if (!result.arch || result.arch.startsWith("--")) { + result.hasHelp = true; + } + break; + default: + if (argv.includes("--steam-upload") && argv[idx].startsWith("-")) { + result.hasHelp = true; + } break; } @@ -119,7 +178,16 @@ export const parseArgv = (argv: string[]): ParsedArgs => } } - if (!result.platform || !result.environment) { + if (!result.platform && !result.steamUpload || !result.environment || result.environment.startsWith("--")) { + result.hasHelp = true; + } + if (result.steamManifest && (!result.platform.startsWith("steam:") || result.preview || result.open || result.build || result.arch)) { + result.hasHelp = true; + } + if (result.steamUpload && (result.platform || result.steamManifest || result.preview || result.open || result.build || result.arch || result.v8Root)) { + result.hasHelp = true; + } + if (!result.steamUpload && (result.steamBranch || result.steamRoot || result.steamComment || result.dryRun)) { result.hasHelp = true; } @@ -169,8 +237,15 @@ Please update your version of Node.`); ctx.open = parsed.open; ctx.build = parsed.build; ctx.v8Root = parsed.v8Root; + ctx.arch = parsed.arch; + ctx.steamManifest = parsed.steamManifest; + ctx.steamUpload = parsed.steamUpload; + ctx.steamBranch = parsed.steamBranch; + ctx.steamRoot = parsed.steamRoot; + ctx.steamComment = parsed.steamComment; + ctx.dryRun = parsed.dryRun; - if (parsed.hasHelp || !SUPPORTED_PLATFORMS.has(ctx.platform)) { + if (parsed.hasHelp || !ctx.steamUpload && !SUPPORTED_PLATFORMS.has(ctx.platform)) { echoHelp(); } diff --git a/src/colors.ts b/src/colors.ts new file mode 100644 index 0000000..8e69ccf --- /dev/null +++ b/src/colors.ts @@ -0,0 +1,8 @@ +// Node handles TTY detection, NO_COLOR and FORCE_COLOR without a logging dependency. +import { styleText } from "node:util"; + +export default { + "red": (value: unknown): string => styleText("red", String(value)), + "green": (value: unknown): string => styleText("green", String(value)), + "yellow": (value: unknown): string => styleText("yellow", String(value)) +}; diff --git a/src/context.ts b/src/context.ts index f721a15..99a69f5 100644 --- a/src/context.ts +++ b/src/context.ts @@ -19,8 +19,17 @@ export interface BuildContext { build: boolean; /** --v8-root (Xbox) */ v8Root: string; + /** Electron CPU architecture (--arch); empty selects a platform default. */ + arch: string; + /** Generate shared Steam depot manifests from existing packages only. */ + steamManifest: boolean; + steamUpload: boolean; + steamBranch: string; + steamRoot: string; + steamComment: string; + dryRun: boolean; /** vite の loadConfigFromFile 結果 */ - configObject: any | null; + configObject: Awaited>; /** ビルド出力ディレクトリ (dist//) */ buildDir: string; /** vite build.outDir (既定 "dist") */ @@ -39,6 +48,13 @@ export const ctx: BuildContext = { "open": false, "build": false, "v8Root": "", + "arch": "", + "steamManifest": false, + "steamUpload": false, + "steamBranch": "", + "steamRoot": "", + "steamComment": "", + "dryRun": false, "configObject": null, "buildDir": "", "outDir": "dist", diff --git a/src/description.ts b/src/description.ts new file mode 100644 index 0000000..7a7ea0b --- /dev/null +++ b/src/description.ts @@ -0,0 +1,8 @@ +/** An explicit empty string is intentional; null/undefined use package metadata. */ +export const resolveDescription = (description: unknown, fallback: unknown): string => { + const value = description ?? fallback ?? ""; + if (typeof value !== "string") { + throw new Error("App description must be a string."); + } + return value; +}; diff --git a/src/electron-config.ts b/src/electron-config.ts new file mode 100644 index 0000000..b7331cc --- /dev/null +++ b/src/electron-config.ts @@ -0,0 +1,135 @@ +import fs from "node:fs"; +import path from "node:path"; +import { getTemplateDir } from "./utils.js"; +import { resolveDescription } from "./description.js"; + +export type ElectronOS = "windows" | "macos" | "linux"; +export interface IElectronConfig { + appId: string; + appName: string; + description: string; + executableName: string; + companyName: string; + icons: Partial>; + architectures: Partial>; + window: { width: number; height: number; fullscreen: boolean }; + steam?: { appId: string | null; depots: Partial>; branch?: string }; + macos: { sign: boolean; notarize: boolean }; +} + +export const validateSteamId = (value: unknown): string => { + const id = String(value); + if (!/^[1-9][0-9]*$/.test(id) || !Number.isSafeInteger(Number(id)) || Number(id) > 4294967295) { + throw new Error("Steam App ID and Depot IDs must be positive 32-bit integers."); + } + return id; +}; + +export const readElectronConfig = (root: string): IElectronConfig => { + const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")); + const file = path.join(root, "electron.config.json"); + const input = fs.existsSync(file) ? JSON.parse(fs.readFileSync(file, "utf8")) : {}; + const config: IElectronConfig = { + "appId": input.appId ?? `app.next2d.${pkg.name}`, + "appName": input.appName ?? pkg.name, + "description": resolveDescription(input.description, pkg.description), + "executableName": input.executableName ?? pkg.name, + "companyName": input.companyName ?? pkg.author?.name ?? input.appName ?? pkg.name, + "icons": { + "windows": path.join(getTemplateDir("electron"), "icons/icon.ico"), + "macos": path.join(getTemplateDir("electron"), "icons/icon.icns"), + "linux": path.join(getTemplateDir("electron"), "icons/icon.png"), + ...input.icons + }, + "architectures": input.architectures ?? {}, + "window": { "width": 1280, "height": 720, "fullscreen": false, ...input.window }, + "macos": { "sign": false, "notarize": false, ...input.macos }, + "steam": input.steam + }; + if (typeof config.appId !== "string" || !/^[A-Za-z0-9-]+(?:\.[A-Za-z0-9-]+)+$/.test(config.appId)) { + throw new Error("electron.config.json appId must be a reverse-domain bundle identifier."); + } + for (const [key, value] of [["appName", config.appName], ["executableName", config.executableName]]) { + if (typeof value !== "string" || !value.trim() || /[<>:"/\\|?*\x00-\x1f]/.test(value) || /[. ]$/.test(value) || value === "..") { + throw new Error(`electron.config.json ${key} must be a valid portable file name.`); + } + } + if (typeof config.companyName !== "string" || !config.companyName.trim()) { + throw new Error("electron.config.json companyName must be a nonempty string."); + } + for (const dimension of [config.window.width, config.window.height]) { + if (!Number.isInteger(dimension) || dimension < 1 || dimension > 16384) { + throw new Error("Electron window width/height must be integers between 1 and 16384."); + } + } + for (const value of [config.window.fullscreen, config.macos.sign, config.macos.notarize]) { + if (typeof value !== "boolean") { + throw new Error("Electron fullscreen/sign/notarize options must be booleans."); + } + } + if (config.macos.notarize && !config.macos.sign) { + throw new Error("macos.notarize requires macos.sign."); + } + for (const os of ["windows", "macos", "linux"] as const) { + const icon = config.icons[os]; + if (icon !== undefined) { + const extension = { "windows": ".ico", "macos": ".icns", "linux": ".png" }[os]; + if (typeof icon !== "string" || path.extname(icon).toLowerCase() !== extension || !fs.statSync(path.resolve(root, icon), { "throwIfNoEntry": false })?.isFile()) { + throw new Error(`electron.config.json icons.${os} must point to an existing ${extension} file (relative to the project root).`); + } + } + const arch = config.architectures[os]; + if (arch !== undefined && !(os === "macos" ? ["x64", "arm64", "universal"] : ["x64", "arm64"]).includes(arch)) { + throw new Error(`Invalid electron.config.json architectures.${os}.`); + } + } + if (config.steam) { + config.steam.appId = config.steam.appId === null || config.steam.appId === undefined ? null : validateSteamId(config.steam.appId); + const depots = config.steam.depots ?? {}; + const ids = Object.values(depots).filter((value) => value !== null).map(validateSteamId); + if (ids.length && !config.steam.appId) { + throw new Error("Set steam.appId before configuring Steam Depot IDs."); + } + config.steam.depots = depots; + } + return config; +}; + +/** JSON is the source of game metadata; secrets stay in the environment/keychain. */ +export const createElectronPackagerOptions = ( + root: string, config: IElectronConfig, os: ElectronOS, resources: string +) => { + const pkg = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")); + const release = process.env.NEXT2D_STEAM_RELEASE === "1"; + const sign = config.macos.sign || release; + const notarize = config.macos.notarize || release; + if (os === "macos" && sign && !process.env.APPLE_SIGNING_IDENTITY) { + throw new Error("macOS signing requires APPLE_SIGNING_IDENTITY."); + } + if (os === "macos" && notarize && !process.env.APPLE_NOTARY_PROFILE) { + throw new Error("macOS notarization requires APPLE_NOTARY_PROFILE (notarytool keychain profile)."); + } + return { + "name": config.appName, + "executableName": config.executableName, + "appBundleId": config.appId, + "appVersion": pkg.version, + "win32metadata": { "CompanyName": config.companyName, "FileDescription": config.description }, + "asar": true, + "extraResource": [resources], + "ignore": [/^\/resources(?:\/|$)/, /^\/icons(?:\/|$)/, /^\/forge\.config\.[cm]?js$/, /^\/entitlements\.plist$/, /(?:^|\/)steam_appid\.txt$/], + ...os !== "linux" && config.icons[os] ? { "icon": path.resolve(root, config.icons[os]) } : {}, + ...os === "macos" && sign ? { + "osxSign": { + "identity": process.env.APPLE_SIGNING_IDENTITY, + // Packager otherwise swallows signing failures and attempts notarization. + "continueOnError": false, + "optionsForFile": () => ({ + "hardenedRuntime": true, + "entitlements": path.join(getTemplateDir("electron"), "entitlements.plist") + }) + } + } : {}, + ...os === "macos" && notarize ? { "osxNotarize": { "keychainProfile": process.env.APPLE_NOTARY_PROFILE! } } : {} + }; +}; diff --git a/src/electron-host.ts b/src/electron-host.ts new file mode 100644 index 0000000..9048a1d --- /dev/null +++ b/src/electron-host.ts @@ -0,0 +1,46 @@ +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { getTemplateDir } from "./utils.js"; +import type { IElectronConfig } from "./electron-config.js"; + +/** The builder pins the runtime; games need neither Electron nor its npm dependency tree. */ +export const getElectronVersion = (): string => { + const pkg = JSON.parse(fs.readFileSync(path.join(getTemplateDir("electron"), "package.json"), "utf8")); + const version = pkg.devDependencies.electron; + if (typeof version !== "string" || !/^\d+\.\d+\.\d+$/.test(version)) { + throw new Error("The builder's Electron template must pin an exact runtime version."); + } + return version; +}; + +/** No user files are written or removed. Each build gets an isolated, disposable host. */ +export const withElectronHost = async ( + root: string, resources: string, config: IElectronConfig, use: (directory: string) => Promise +): Promise => { + if (!fs.statSync(path.join(resources, "index.html"), { "throwIfNoEntry": false })?.isFile()) { + throw new Error(`Electron web entry point is missing: ${resources}/index.html`); + } + const game = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")); + const dir = fs.mkdtempSync(path.join(os.tmpdir(), "next2d-electron-")); + try { + for (const file of ["index.js", "local-assets.cjs"]) { + fs.copyFileSync(path.join(getTemplateDir("electron"), file), path.join(dir, file)); + } + const pkg = { + "name": game.name, "version": game.version, "description": config.description, + "private": true, "type": "commonjs", "main": "index.js" + }; + fs.writeFileSync(path.join(dir, "package.json"), `${JSON.stringify(pkg, null, 2)}\n`); + fs.cpSync(resources, path.join(dir, "resources"), { "recursive": true }); + const runtime = { "appId": config.appId, "appName": config.appName, "window": config.window, "icon": "" }; + if (config.icons.linux) { + fs.copyFileSync(path.resolve(root, config.icons.linux), path.join(dir, "resources/desktop-icon.png")); + runtime.icon = "desktop-icon.png"; + } + fs.writeFileSync(path.join(dir, "runtime-config.json"), `${JSON.stringify(runtime, null, 2)}\n`); + return await use(dir); + } finally { + fs.rmSync(dir, { "recursive": true, "force": true }); + } +}; diff --git a/src/electron.ts b/src/electron.ts index bce08e7..dc9be0b 100644 --- a/src/electron.ts +++ b/src/electron.ts @@ -1,178 +1,101 @@ -// Electron ベースのデスクトップ配布 (Steam / Epic Games Store など)。 -import pc from "picocolors"; -import fs from "fs"; -import cp from "child_process"; -import { api } from "@electron-forge/core"; +// Electron desktop packages are unpacked application folders, ready for SteamPipe. +import pc from "./colors.js"; +import fs from "node:fs"; +import path from "node:path"; +import { createRequire } from "node:module"; +import { pathToFileURL } from "node:url"; +import { createElectronPackagerOptions, readElectronConfig } from "./electron-config.js"; +import type { ElectronOS } from "./electron-config.js"; import { ctx } from "./context.js"; import { $spawn } from "./utils.js"; - -/** - * @description electronがインストールされてなければインストールを実行 - * If electron is not installed, run install. - * - * @return {Promise} - * @method - * @private - */ -const installElectron = (): Promise => -{ - return new Promise((resolve, reject): void => - { - if (fs.existsSync(`${process.cwd()}/electron/node_modules`)) { - return resolve(); - } - - const stream = $spawn("npm", [ - "--prefix", - `${process.cwd()}/electron`, - "install", - `${process.cwd()}/electron` - ], { "stdio": "inherit" }); - - stream.on("close", (code: number): void => - { - if (code !== 0) { - reject("`Electron` installation failed."); - } - - console.log(pc.green("`Electron` successfully installed.")); - resolve(); - }); - }); +import { getElectronVersion, withElectronHost } from "./electron-host.js"; +import { findSteamLaunch, recordSteamPackage, writeSharedSteamDepots } from "./steam.js"; +import { resolveToolPackages } from "./tool-packages.js"; + +export const resolveElectronTarget = (platform: string, arch = "", preview = false): { + platform: "win32" | "darwin" | "linux"; + arch: "x64" | "arm64" | "universal"; +} => { + const os = platform.replace(/^steam:/, ""); + const target = { "windows": "win32", "macos": "darwin", "linux": "linux" }[os]; + if (target !== "win32" && target !== "darwin" && target !== "linux") { + throw new Error(`Unsupported Electron platform: ${platform}`); + } + const cpu = arch || (preview ? process.arch : target === "darwin" ? "universal" : "x64"); + if (cpu !== "x64" && cpu !== "arm64" && cpu !== "universal") { + throw new Error(`Unsupported Electron architecture: ${cpu}`); + } + if (cpu === "universal" && target !== "darwin") { + throw new Error("--arch universal is only supported for macOS."); + } + if (preview && (target !== process.platform || cpu !== process.arch)) { + throw new Error("Electron preview must use the host OS and architecture."); + } + return { "platform": target, "arch": cpu }; }; -/** - * @description electronに含むリソースを初期化 - * Initialize resources included in electron - * - * @return {Promise} - * @method - * @private - */ -const removeResources = (): Promise => -{ - return new Promise((resolve, reject): void => - { - const stream = cp.spawn("rm", [ - "-rf", - `${process.cwd()}/electron/resources/` - ], { "stdio": "inherit" }); - - stream.on("close", (code: number): void => - { +const run = (command: string, args: string[], cwd: string): Promise => + new Promise((resolve, reject) => { + const child = $spawn(command, args, { cwd, "stdio": "inherit" }); + child.once("error", reject); + child.once("close", (code, signal) => { if (code !== 0) { - reject("Failed to remove built resources."); + reject(new Error(`${command} failed (${signal || code}).`)); + return; } - - console.log(pc.green("Successfully remove built resources.")); resolve(); }); }); -}; - -/** - * @description ビルドしたリソースをコピー - * Copy built resources - * - * @return {Promise} - * @method - * @private - */ -const copyResources = (): Promise => -{ - return new Promise((resolve, reject): void => - { - const stream = cp.spawn("cp", [ - "-r", - `${ctx.buildDir}/`, - `${process.cwd()}/electron/resources` - ], { "stdio": "inherit" }); - stream.on("close", (code: number): void => - { - if (code !== 0) { - reject("Failed to copy built resources."); - } - - console.log(pc.green("Successfully copy built resources.")); - resolve(); - }); +export const buildElectron = async (): Promise => { + const root = process.cwd(); + const config = readElectronConfig(root); + const os = ctx.platform.replace(/^steam:/, "") as ElectronOS; + const target = resolveElectronTarget(ctx.platform, ctx.arch || (ctx.preview ? "" : config.architectures[os]), ctx.preview); + if (target.arch === "universal" && process.platform !== "darwin") { + throw new Error("Build universal macOS applications on macOS."); + } + const steam = ctx.platform.startsWith("steam:"); + const version: string = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")).version; + const steamRoot = path.resolve(ctx.outDir, "steam"); + const outDir = path.resolve(ctx.outDir, ctx.platformDir, "build", ctx.environment); + if (steam) { + // A failed rebuild must not leave a shared manifest pointing at partially replaced files. + fs.rmSync(path.join(outDir, "steam-package.json"), { "force": true }); + writeSharedSteamDepots(steamRoot, ctx.environment, config, version); + } + const outputPaths = await withElectronHost(root, ctx.buildDir, config, async (dir) => { + const options = createElectronPackagerOptions(root, config, os, path.join(dir, "resources")); + if (steam && os === "macos" && !options.osxNotarize) { + console.log(pc.yellow("Local macOS build: unsigned/unnotarized builds must not be submitted for Steam release. See docs/steam.md.")); + } + console.log(pc.green(`Packaging Electron (${target.platform}/${target.arch})`)); + const packages = await resolveToolPackages("electron"); + const require = createRequire(packages["@electron/packager"]); + const { packager } = await import(pathToFileURL(require.resolve("@electron/packager")).href); + // The generated host has no npm dependencies or native addons. Packager downloads + // the pinned Electron runtime directly and uses its normal download cache. + return await packager({ + ...options, dir, ...target, + "out": outDir, + "electronVersion": getElectronVersion(), + "overwrite": true, + "prune": false + }) as string[]; }); -}; - -/** - * @description Electron ベースのデスクトップアプリ書き出し関数 - * (Windows / macOS / Linux、Steam・Epic Games Store 等の配布に共通)。 - * Export function for Electron-based desktop apps. - * - * @return {Promise} - * @method - * @public - */ -export const buildElectron = async (): Promise => -{ - // reset - await removeResources(); - - // copy HTML, JavaScript - await copyResources(); - - if (ctx.preview) { - - $spawn("npx", [ - "electron", - `${process.cwd()}/electron/index.js` - ], { "stdio": "inherit" }); - - } else { - - await installElectron(); - - console.log(pc.green("Start the `Electron` build process.")); - console.log(); - - const packageOptions = { - "dir": `${process.cwd()}/electron`, - "outDir": `${ctx.outDir}/${ctx.platformDir}/build`, - "platform": "", - "arch": "all" - }; - - switch (ctx.platform) { - - case "windows": - case "steam:windows": - packageOptions.platform = "win32"; - break; - - case "macos": - case "steam:macos": - packageOptions.platform = "mas"; - break; - - case "linux": - case "steam:linux": - packageOptions.platform = "linux"; - break; - - default: - console.log(pc.red("There is an error in the export platform settings.")); - console.log(); - process.exit(1); - + if (steam) { + for (const content of outputPaths) { + recordSteamPackage(content, ctx.platform, target.arch, config, version); } - - api - .package(packageOptions) - .then((): void => - { - console.log(pc.green(`Finished building \`Electron\` for ${ctx.platform}.`)); - console.log(); - }) - .catch((error: any): void => - { - console.log(pc.red("Export of Electron failed.")); - console.log(pc.red(error)); - }); + writeSharedSteamDepots(steamRoot, ctx.environment, config, version); + } + console.log(pc.green(`Finished Electron export: ${outDir}`)); + if (ctx.preview) { + const content = outputPaths[0]; + const launch = findSteamLaunch(content, `steam:${os}`, config.executableName); + const executable = target.platform === "darwin" + ? path.join(content, launch, "Contents/MacOS", config.executableName) + : path.join(content, launch); + await run(executable, [], root); } }; diff --git a/src/index.ts b/src/index.ts index 1d83416..54d630e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,11 @@ import { loadConfig, buildWeb } from "./web.js"; import { buildElectron } from "./electron.js"; import { runNative, openNative, buildNative } from "./native.js"; import { buildXbox } from "./xbox.js"; +import fs from "node:fs"; +import path from "node:path"; +import { readElectronConfig } from "./electron-config.js"; +import { writeSharedSteamDepots } from "./steam.js"; +import { uploadSteam } from "./steam-upload.js"; // Node バージョン検証・引数解析・ctx 初期化 (不正時はここで終了)。 initCli(); @@ -82,7 +87,23 @@ const multiBuild = async (): Promise => const execute = async (): Promise => { try { + if (ctx.steamUpload) { + await uploadSteam({ + "root": process.cwd(), "steamRoot": ctx.steamRoot || "dist/steam", "environment": ctx.environment, + "branch": ctx.steamBranch || undefined, "comment": ctx.steamComment || undefined, "dryRun": ctx.dryRun + }); + return; + } await loadConfig(); + if (ctx.steamManifest) { + const config = readElectronConfig(process.cwd()); + const version: string = JSON.parse(fs.readFileSync("package.json", "utf8")).version; + const pending = writeSharedSteamDepots(path.resolve(ctx.outDir, "steam"), ctx.environment, config, version); + if (pending.length) { + throw new Error(`Shared Steam depots are incomplete. Export or collect all required OS packages first.\n${pending.join("\n")}`); + } + return; + } await buildWeb(); await multiBuild(); } catch (error) { diff --git a/src/native.ts b/src/native.ts index 07f468a..4d5fb6c 100644 --- a/src/native.ts +++ b/src/native.ts @@ -1,158 +1,73 @@ -// iOS / Android (Capacitor) ビルド。 -import pc from "picocolors"; -import fs from "fs"; +// iOS / Android (Capacitor) ビルド。SDKとCLIはnpxで必要時に取得する。 +import fs from "node:fs"; +import path from "node:path"; import { ctx } from "./context.js"; import { $spawn } from "./utils.js"; import { CAPACITOR_CONFIG_NAME } from "./constants.js"; +import { resolveToolPackages } from "./tool-packages.js"; + +/** Resolve from npm's persistent tool cache without installing into the game. */ +export const getCapacitorCommand = async (): Promise<{ cli: string; env: NodeJS.ProcessEnv }> => { + const resolved = await resolveToolPackages("capacitor"); + const packages = ["cli", "core", "ios", "android"].map((name) => + resolved[`@capacitor/${name}`]); + // Keep the game's cwd for plugin discovery/hooks; supply SDKs through NODE_PATH. + const roots = [...new Set(packages.map((file) => path.dirname(path.dirname(path.dirname(file)))))]; + return { + "cli": path.join(path.dirname(packages[0]), "bin", "capacitor"), + "env": { ...process.env, "NODE_PATH": [...roots, process.env.NODE_PATH].filter(Boolean).join(path.delimiter) } + }; +}; -/** - * @description iOS/Androidのプロジェクトを生成 - * Generate iOS/Android project - * - * @return {Promise} - * @method - * @private - */ -const generateNativeProject = (): Promise => -{ - return new Promise((resolve, reject): void => - { - if (fs.existsSync(`${process.cwd()}/${ctx.platform}`)) { - return resolve(); - } - - const stream = $spawn("npx", [ - "cap", - "add", - ctx.platform - ], { "stdio": "inherit" }); - - stream.on("close", (code: number): void => - { +/** Await every CLI operation so failures propagate to the builder and CI. */ +export const runCapacitor = async (args: string[], root = process.cwd()): Promise => { + const { cli, env } = await getCapacitorCommand(); + return new Promise((resolve, reject) => { + const child = $spawn(process.execPath, [cli, ...args], { "cwd": root, env, "stdio": "inherit" }); + child.once("error", reject); + child.once("close", (code, signal) => { if (code !== 0) { - reject(`Failed generated ${ctx.platform} project.`); + reject(new Error(`Capacitor ${args.join(" ")} failed (${signal || code}).`)); + return; } - - console.log(pc.green(`Successfully generated ${ctx.platform} project.`)); - console.log(); - resolve(); }); }); }; -/** - * @description Capacitor の webDir を現在のビルド出力へ書き換える - * Point the Capacitor webDir at the current build output - * - * @return {void} - * @method - * @private - */ -const applyCapacitorWebDir = (): void => -{ - const config = JSON.parse( - fs.readFileSync(`${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, { "encoding": "utf8" }) - ); - - config.webDir = `${ctx.outDir}/${ctx.platformDir}/${ctx.environment}/`; - - fs.writeFileSync( - `${process.cwd()}/${CAPACITOR_CONFIG_NAME}`, - JSON.stringify(config, null, 2) - ); +const prepareNativeProject = async (): Promise => { + if (ctx.platform !== "ios" && ctx.platform !== "android") { + throw new Error(`Unsupported Capacitor platform: ${ctx.platform}`); + } + const root = process.cwd(); + const file = path.join(root, CAPACITOR_CONFIG_NAME); + const config = JSON.parse(fs.readFileSync(file, "utf8")); + // cap add performs an initial sync, so it must see the new webDir too. + config.webDir = path.relative(root, path.resolve(ctx.outDir, ctx.platformDir, ctx.environment)).replace(/\\/g, "/") + "/"; + fs.writeFileSync(file, JSON.stringify(config, null, 2) + "\n"); + const platformDir = path.resolve(root, config[ctx.platform]?.path ?? ctx.platform); + if (!fs.existsSync(platformDir)) { + await runCapacitor(["add", ctx.platform]); + } }; -/** - * @description iOS用アプリの書き出し関数 - * Export function for iOS apps - * - * @return {Promise} - * @method - * @public - */ -export const runNative = async (): Promise => -{ - await generateNativeProject(); - - // Capacitorの書き出しに必要な設定を生成 - applyCapacitorWebDir(); - - $spawn("npx", [ - "cap", - "run", - ctx.platform - ], { "stdio": "inherit" }); +/** Keep native customizations and update web assets/dependency paths in place. */ +export const syncNative = async (): Promise => { + await prepareNativeProject(); + await runCapacitor(["sync", ctx.platform]); }; -/** - * @description iOS/Androidアプリのオープン関数 - * Open function for iOS/Android apps - * - * @return {Promise} - * @method - * @public - */ -export const openNative = async (): Promise => -{ - await generateNativeProject(); - - // Capacitorの書き出しに必要な設定を生成 - applyCapacitorWebDir(); - - const stream = $spawn("npx", [ - "cap", - "sync", - ctx.platform - ], { "stdio": "inherit" }); - - stream.on("close", (code: number): void => - { - if (code !== 0) { - console.log(pc.red(`Failed to sync ${ctx.platform} project.`)); - return; - } - - $spawn("npx", [ - "cap", - "open", - ctx.platform - ], { "stdio": "inherit" }); - }); +export const runNative = async (): Promise => { + await prepareNativeProject(); + await runCapacitor(["run", ctx.platform]); }; -/** - * @description iOS/Androidアプリのビルド関数 - * Build function for iOS/Android apps - * - * @return {Promise} - * @method - * @public - */ -export const buildNative = async (): Promise => -{ - await generateNativeProject(); - - // Capacitorの書き出しに必要な設定を生成 - applyCapacitorWebDir(); - - const stream = $spawn("npx", [ - "cap", - "sync", - ctx.platform - ], { "stdio": "inherit" }); - - stream.on("close", (code: number): void => - { - if (code !== 0) { - console.log(pc.red(`Failed to sync ${ctx.platform} project.`)); - return; - } +export const openNative = async (): Promise => { + await syncNative(); + await runCapacitor(["open", ctx.platform]); +}; - $spawn("npx", [ - "cap", - "build", - ctx.platform - ], { "stdio": "inherit" }); - }); +export const buildNative = async (): Promise => { + await syncNative(); + await runCapacitor(["build", ctx.platform]); }; diff --git a/src/project-vite.ts b/src/project-vite.ts new file mode 100644 index 0000000..05f0686 --- /dev/null +++ b/src/project-vite.ts @@ -0,0 +1,22 @@ +import { createRequire } from "node:module"; +import path from "node:path"; +import { pathToFileURL } from "node:url"; +import type * as Vite from "vite"; + +/** Resolve from the game, including when builder is launched through npx or a sibling checkout. */ +export const loadProjectVite = async (root = process.cwd()): Promise => { + const require = createRequire(path.join(root, "package.json")); + let entry: string; + try { + entry = require.resolve("vite"); + } catch { + throw new Error(`Vite is not installed in ${root}. Install the game's dependencies with npm install first.`); + } + const imported = await import(pathToFileURL(entry).href); + // Vite 7's require condition resolves to its CJS API wrapper; Vite 8 is ESM. + const vite = imported.default ?? imported; + if (typeof vite.loadConfigFromFile !== "function") { + throw new Error(`The Vite installation in ${root} does not expose loadConfigFromFile.`); + } + return vite; +}; diff --git a/src/resolve-tool-packages.ts b/src/resolve-tool-packages.ts new file mode 100644 index 0000000..4549431 --- /dev/null +++ b/src/resolve-tool-packages.ts @@ -0,0 +1,30 @@ +// Runs inside npx, where the downloaded tools' node_modules/.bin is on PATH. +import fs from "node:fs"; +import path from "node:path"; + +const packages: Record = JSON.parse(process.env.NEXT2D_TOOL_PACKAGES!); +let resolved: Record | undefined; +for (const bin of (process.env.PATH ?? "").split(path.delimiter)) { + if (path.basename(bin) !== ".bin") { + continue; + } + const files: Record = {}; + for (const [name, version] of Object.entries(packages)) { + const file = path.join(path.dirname(bin), name, "package.json"); + if (fs.existsSync(file)) { + const pkg = JSON.parse(fs.readFileSync(file, "utf8")); + if (pkg.name === name && pkg.version === version) { + files[name] = file; + } + } + } + // All SDKs must come from the same installation, with the requested exact versions. + if (Object.keys(files).length === Object.keys(packages).length) { + resolved = files; + break; + } +} +if (!resolved) { + throw new Error("Could not resolve the requested build tools from npx's PATH."); +} +fs.writeFileSync(process.env.NEXT2D_TOOL_RESULT!, JSON.stringify(resolved)); diff --git a/src/steam-upload.ts b/src/steam-upload.ts new file mode 100644 index 0000000..75ea205 --- /dev/null +++ b/src/steam-upload.ts @@ -0,0 +1,146 @@ +import fs from "node:fs"; +import path from "node:path"; +import { spawn } from "node:child_process"; +import { readElectronConfig, validateSteamId } from "./electron-config.js"; +import { quoteSteamValue as quote, readSteamPackage } from "./steam.js"; + +export interface ISteamUploadOptions { + root: string; + steamRoot: string; + environment: string; + branch?: string; + comment?: string; + dryRun?: boolean; +} + +export const validateSteamBranch = (branch: unknown): string => { + if (typeof branch !== "string" || !/^[a-zA-Z0-9][a-zA-Z0-9_-]{0,63}$/.test(branch) + || ["default", "public", "none"].includes(branch.toLowerCase())) { + throw new Error("Steam upload requires a named beta branch such as internal (letters, numbers, - or _). The default branch is not supported."); + } + return branch; +}; + +/** Recreate manifests from validated package records, never from stale or edited VDF files. */ +export const prepareSteamUpload = (options: ISteamUploadOptions) => { + const root = path.resolve(options.root); + const steamRoot = path.resolve(root, options.steamRoot); + if (!/^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(options.environment)) { + throw new Error("Steam upload --env must contain only letters, numbers, - or _."); + } + const config = readElectronConfig(root); + const branch = validateSteamBranch(options.branch ?? config.steam?.branch ?? "internal"); + if (!config.steam?.appId) { + throw new Error("Set steam.appId and steam.depots in electron.config.json before uploading."); + } + const version = JSON.parse(fs.readFileSync(path.join(root, "package.json"), "utf8")).version; + if (typeof version !== "string" || !version) { + throw new Error("Set package.json version before uploading."); + } + if (options.comment !== undefined && (typeof options.comment !== "string" || !options.comment.trim() + || /["\\\u0000-\u001f\u007f]/.test(options.comment))) { + throw new Error("Steam upload --steam-comment must be nonempty single-line text without double quotes, backslashes or control characters."); + } + const comment = options.comment ?? `${config.appName} ${version} (${options.environment}, ${branch})`; + const quotedComment = quote(comment); + const groups = new Map(); + for (const os of ["windows", "macos", "linux"] as const) { + const id = config.steam.depots[os]; + if (id === null || id === undefined) { + continue; + } + const depot = validateSteamId(id); + try { + const record = readSteamPackage(steamRoot, options.environment, config, version, os); + groups.set(depot, [...groups.get(depot) ?? [], { os, ...record }]); + } catch (error) { + throw new Error(`Steam upload: ${os} package is missing or outdated. Export/collect every configured OS first. ${error instanceof Error ? error.message : error}`); + } + } + if (!groups.size) { + throw new Error("Set at least one Steam Depot ID in electron.config.json before uploading."); + } + // Unique scripts prevent a dry-run or another invocation from overwriting an active upload. + const uploads = path.join(steamRoot, "uploads", options.environment); + fs.mkdirSync(uploads, { "recursive": true }); + const scripts = fs.mkdtempSync(path.join(uploads, `${branch}-`)); + const depotFiles: string[] = []; + const launches: { platform: string; arch: string; executable: string; depotId: string }[] = []; + for (const [depot, members] of groups) { + const mappings = members.map(({ os, content, arch, localExecutable }) => { + const prefix = members.length > 1 ? `${os}/` : ""; + launches.push({ "platform": `steam:${os}`, arch, "executable": `${prefix}${localExecutable}`, "depotId": depot }); + return ` "FileMapping"\n {\n "LocalPath" ${quote(`${path.relative(steamRoot, content)}/*`)}\n "DepotPath" ${quote(prefix || ".")}\n "Recursive" "1"\n }`; + }); + const name = `depot_${depot}.vdf`; + fs.writeFileSync(path.join(scripts, name), + `"DepotBuild"\n{\n "DepotID" "${depot}"\n${mappings.join("\n")}\n "FileExclusion" "steam_appid.txt"\n "FileExclusion" "*.pdb"\n "FileExclusion" ".DS_Store"\n}\n`); + depotFiles.push(` "${depot}" ${quote(name)}`); + } + const manifest = path.join(scripts, options.dryRun ? "app_preview.vdf" : "app_upload.vdf"); + // A stable cache directory allows SteamPipe to reuse chunks across uploads to a branch. + const cache = path.join(uploads, "cache", branch); + fs.writeFileSync(manifest, + `"AppBuild"\n{\n "AppID" "${config.steam.appId}"\n "Desc" ${quotedComment}\n` + + ` "ContentRoot" ${quote(steamRoot)}\n "BuildOutput" ${quote(cache)}\n "Preview" "${options.dryRun ? "1" : "0"}"\n` + + (options.dryRun ? "" : ` "SetLive" ${quote(branch)}\n`) + + ` "Depots"\n {\n${depotFiles.join("\n")}\n }\n}\n`); + const plan = { "appId": config.steam.appId, branch, version, comment, "environment": options.environment, "dryRun": !!options.dryRun, manifest, launches }; + fs.writeFileSync(path.join(scripts, "upload-plan.json"), `${JSON.stringify(plan, null, 2)}\n`); + return plan; +}; + +/** Use SteamCMD's existing login session; passwords/Steam Guard codes never enter project config. */ +export const uploadSteam = async (options: ISteamUploadOptions): Promise => { + const plan = prepareSteamUpload(options); + console.log(`Steam App ${plan.appId} -> beta branch ${plan.branch}`); + console.log(`Comment: ${plan.comment}`); + console.log(`Manifest: ${plan.manifest}`); + for (const launch of plan.launches) { + console.log(` Depot ${launch.depotId}: ${launch.platform}/${launch.arch} -> ${launch.executable}`); + } + if (options.dryRun) { + console.log("Dry run complete: SteamCMD was not started. Branch existence/password protection has not been checked on Steamworks."); + return; + } + const username = process.env.STEAM_USERNAME; + if (!username || !/^[a-zA-Z0-9_][a-zA-Z0-9_.@-]*$/.test(username)) { + throw new Error("Set STEAM_USERNAME to your Steam build account name. Log in with SteamCMD once before uploading; see docs/steam.md."); + } + const command = process.env.STEAMCMD || (process.platform === "win32" ? "steamcmd.exe" : "steamcmd"); + console.log(`Uploading and requesting activation on ${plan.branch}. Configure the beta password in Steamworks to restrict access.`); + const buildId = await new Promise((resolve, reject) => { + let output = ""; + let reportedError = false; + const child = spawn(command, [ + "+@ShutdownOnFailedCommand", "1", "+@NoPromptForPassword", "1", + "+login", username, "+run_app_build", plan.manifest, "+quit" + ], { "cwd": path.resolve(options.root), "stdio": ["ignore", "pipe", "pipe"], "shell": false }); + const collect = (chunk: Buffer, stream: NodeJS.WriteStream): void => { + stream.write(chunk); + output = (output + chunk.toString()).slice(-1024 * 1024); + reportedError ||= /ERROR[!:]|Failed to set[^\r\n]*live/i.test(output); + }; + child.stdout.on("data", (chunk: Buffer) => collect(chunk, process.stdout)); + child.stderr.on("data", (chunk: Buffer) => collect(chunk, process.stderr)); + child.once("error", (error) => reject(new Error(`Cannot start SteamCMD: ${error.message}. Set STEAMCMD to the executable path; see docs/steam.md.`))); + child.once("close", (code, signal) => { + if (code !== 0) { + reject(new Error(`SteamCMD failed (${signal || code}). Inspect its output and SteamPipe logs; check login, app permissions and beta branch settings.`)); + return; + } + const success = output.match(new RegExp( + `(?:Success! App '${plan.appId}' fully built|Successfully finished AppID ${plan.appId} build) \\(BuildID ([0-9]+)\\)`, "i" + )); + if (reportedError || !success) { + reject(new Error("SteamCMD did not report a successful app build, or reported an error. Check SteamPipe logs and the branch's active BuildID in Steamworks before retrying.")); + return; + } + resolve(success[1]); + }); + }); + fs.writeFileSync(path.join(path.dirname(plan.manifest), "upload-result.json"), `${JSON.stringify({ + "appId": plan.appId, buildId, "requestedBranch": plan.branch, "completedAt": new Date().toISOString() + }, null, 2)}\n`); + console.log(`Uploaded BuildID ${buildId}. Verify the active ${plan.branch} build at https://partner.steamgames.com/apps/builds/${plan.appId}`); +}; diff --git a/src/steam.ts b/src/steam.ts new file mode 100644 index 0000000..4ee18f1 --- /dev/null +++ b/src/steam.ts @@ -0,0 +1,214 @@ +import fs from "node:fs"; +import path from "node:path"; +import { validateSteamId } from "./electron-config.js"; +import type { IElectronConfig, ElectronOS } from "./electron-config.js"; + +export interface ISteamConfig { + appId: string; + depotId: string | null; + sharedPlatforms?: ElectronOS[]; +} + +const platforms: ElectronOS[] = ["windows", "macos", "linux"]; + +export const readSteamConfig = (config: IElectronConfig, platform: string): ISteamConfig | null => { + if (!config.steam?.appId) { + return null; + } + const os = platform.replace(/^steam:/, "") as ElectronOS; + const depot = config.steam.depots[os]; + const depotId = depot ? validateSteamId(depot) : null; + const sharedPlatforms = depotId ? platforms.filter((key) => String(config.steam?.depots[key]) === depotId) : []; + return { "appId": config.steam.appId, depotId, ...sharedPlatforms.length > 1 ? { sharedPlatforms } : {} }; +}; + +export const quoteSteamValue = (value: string): string => { + if (/["\r\n\0]/.test(value)) { + throw new Error("Unsupported quote or control character in SteamPipe path."); + } + return `"${value.replace(/\\/g, "/")}"`; +}; +const quote = quoteSteamValue; + +/** Discover the executable from the output, including customized executable names. */ +export const findSteamLaunch = (content: string, platform: string, executableName?: string): string => { + const entries = fs.readdirSync(content, { "withFileTypes": true }); + if (platform === "steam:macos") { + const apps = entries.filter((entry) => entry.isDirectory() && entry.name.endsWith(".app")); + if (apps.length !== 1) { + throw new Error("Expected exactly one macOS .app in the packaged folder."); + } + return apps[0].name; + } + if (executableName) { + const executable = `${executableName}${platform === "steam:windows" ? ".exe" : ""}`; + if (!fs.statSync(path.join(content, executable), { "throwIfNoEntry": false })?.isFile()) { + throw new Error(`Packaged Steam executable is missing: ${executable}`); + } + return executable; + } + const candidates = entries.filter((entry) => { + if (!entry.isFile()) { + return false; + } + if (platform === "steam:windows") { + return entry.name.endsWith(".exe") && entry.name !== "chrome_crashpad_handler.exe"; + } + // Electron's other Linux binaries have extensions or known helper names. + return !entry.name.includes(".") && !["chrome-sandbox", "chrome_crashpad_handler", "LICENSE", "version"].includes(entry.name) + && (fs.statSync(path.join(content, entry.name)).mode & 0o111) !== 0; + }); + if (candidates.length !== 1) { + throw new Error(`Cannot determine the Steam executable in ${content}`); + } + return candidates[0].name; +}; + +/** Keep scripts outside the content directory so Steam never installs build metadata. */ +export const writeSteamMetadata = (content: string, platform: string, arch: string, config: ISteamConfig | null, executableName?: string): void => { + const localExecutable = findSteamLaunch(content, platform, executableName); + const depotPath = config?.sharedPlatforms ? platform.replace("steam:", "") : ""; + const executable = depotPath ? `${depotPath}/${localExecutable}` : localExecutable; + const scripts = `${content}-steampipe`; + fs.mkdirSync(scripts, { "recursive": true }); + const metadata = { + platform, arch, executable, + localExecutable, depotPath, + "contentRoot": `../${path.basename(content)}`, + "workingDirectory": "", + "arguments": "", + "appId": config?.appId || null, + "depotId": config?.depotId || null + }; + fs.writeFileSync(path.join(scripts, "launch.json"), `${JSON.stringify(metadata, null, 2)}\n`); + // Remove scripts from an earlier configured run if IDs are no longer configured. + for (const name of ["app_build.vdf", "app_preview.vdf", "depot_build.vdf"]) { + fs.rmSync(path.join(scripts, name), { "force": true }); + } + if (!config?.depotId) { + console.log("Steam package ready. Set steam.appId and steam.depots in electron.config.json to generate SteamPipe VDFs."); + return; + } + // Upload a shared depot only through the combined manifest, never one OS at a time. + if (config.sharedPlatforms) { + return; + } + fs.writeFileSync(path.join(scripts, "depot_build.vdf"), `"DepotBuild"\n{\n "DepotID" "${config.depotId}"\n "FileMapping"\n {\n "LocalPath" "*"\n "DepotPath" "."\n "Recursive" "1"\n }\n "FileExclusion" "steam_appid.txt"\n "FileExclusion" "*.pdb"\n "FileExclusion" ".DS_Store"\n}\n`); + for (const preview of [false, true]) { + fs.writeFileSync(path.join(scripts, preview ? "app_preview.vdf" : "app_build.vdf"), + `"AppBuild"\n{\n "AppID" "${config.appId}"\n "Desc" ${quote(`${platform} ${arch}`)}\n "ContentRoot" ${quote(metadata.contentRoot)}\n "BuildOutput" "cache"\n "Preview" "${preview ? "1" : "0"}"\n "Depots"\n {\n "${config.depotId}" "depot_build.vdf"\n }\n}\n`); + } +}; + +/** A portable pointer to the most recently exported architecture for this OS/environment. */ +export const recordSteamPackage = ( + content: string, platform: string, arch: string, config: IElectronConfig, version: string +): void => { + const steam = readSteamConfig(config, platform); + writeSteamMetadata(content, platform, arch, steam, config.executableName); + const record = { + platform, arch, version, + "appId": steam?.appId ?? null, "depotId": steam?.depotId ?? null, + "appName": config.appName, "executableName": config.executableName, + "contentRoot": path.basename(content) + }; + fs.writeFileSync(path.join(path.dirname(content), "steam-package.json"), `${JSON.stringify(record, null, 2)}\n`); +}; + +/** Validate that an exported package still matches the current project and depot configuration. */ +export const readSteamPackage = (steamRoot: string, environment: string, config: IElectronConfig, version: string, os: ElectronOS) => { + const output = path.join(steamRoot, os, "build", environment); + const record = JSON.parse(fs.readFileSync(path.join(output, "steam-package.json"), "utf8")); + if (typeof record.contentRoot !== "string" || path.basename(record.contentRoot) !== record.contentRoot + || /[\\/*?"\r\n\0]/.test(record.contentRoot) || record.contentRoot === "." || record.contentRoot === "..") { + throw new Error("Invalid package path"); + } + const content = path.join(output, record.contentRoot); + if (record.platform !== `steam:${os}` || record.appId !== config.steam?.appId + || record.depotId !== validateSteamId(config.steam?.depots[os]) + || record.version !== version || record.appName !== config.appName || record.executableName !== config.executableName + || !(os === "macos" ? ["x64", "arm64", "universal"] : ["x64", "arm64"]).includes(record.arch)) { + throw new Error("Package metadata no longer matches the project configuration"); + } + const relativeRealPath = path.relative(fs.realpathSync(steamRoot), fs.realpathSync(content)); + if (path.isAbsolute(relativeRealPath) || relativeRealPath === ".." || relativeRealPath.startsWith(`..${path.sep}`)) { + throw new Error("Package directory must be inside the Steam output root"); + } + return { content, "arch": record.arch as string, "localExecutable": findSteamLaunch(content, `steam:${os}`, config.executableName) }; +}; + +/** Combine existing packages with multiple FileMappings, preserving app symlinks and permissions. */ +export const writeSharedSteamDepots = ( + steamRoot: string, environment: string, config: IElectronConfig, version: string +): string[] => { + const pending: string[] = []; + const groups = new Map(); + for (const os of platforms) { + const id = config.steam?.depots[os]; + if (id) { + const key = validateSteamId(id); + groups.set(key, [...groups.get(key) ?? [], os]); + } + } + const sharedRoot = path.join(steamRoot, "shared", environment); + // Remove obsolete generated VDFs after a depot's membership or IDs change. + if (fs.existsSync(sharedRoot)) { + for (const entry of fs.readdirSync(sharedRoot, { "withFileTypes": true })) { + if (entry.isDirectory() && /^depot-[0-9]+$/.test(entry.name)) { + for (const name of ["app_build.vdf", "app_preview.vdf", "depot_build.vdf", "launch.json"]) { + fs.rmSync(path.join(sharedRoot, entry.name, name), { "force": true }); + } + } + } + } + for (const [depotId, members] of groups) { + if (members.length < 2) { + continue; + } + const scripts = path.join(sharedRoot, `depot-${depotId}`); + fs.mkdirSync(scripts, { "recursive": true }); + const mappings: string[] = []; + const launches: { platform: string; arch: string; executable: string; workingDirectory: string; arguments: string }[] = []; + const missing: string[] = []; + for (const os of members) { + const output = path.join(steamRoot, os, "build", environment); + // Also invalidate legacy exports created before steam-package.json existed. + if (fs.existsSync(output)) { + for (const entry of fs.readdirSync(output, { "withFileTypes": true })) { + if (entry.isDirectory() && entry.name.startsWith(`${config.appName}-`) && entry.name.endsWith("-steampipe")) { + for (const name of ["app_build.vdf", "app_preview.vdf", "depot_build.vdf"]) { + fs.rmSync(path.join(output, entry.name, name), { "force": true }); + } + } + } + } + try { + const { content, arch, localExecutable } = readSteamPackage(steamRoot, environment, config, version, os); + const relative = path.relative(steamRoot, content).replace(/\\/g, "/"); + mappings.push(` "FileMapping"\n {\n "LocalPath" ${quote(`${relative}/*`)}\n "DepotPath" "${os}/"\n "Recursive" "1"\n }`); + launches.push({ "platform": `steam:${os}`, arch, "executable": `${os}/${localExecutable}`, "workingDirectory": "", "arguments": "" }); + writeSteamMetadata(content, `steam:${os}`, arch, readSteamConfig(config, `steam:${os}`), config.executableName); + } catch (error) { + missing.push(`${os}: ${error instanceof Error ? error.message : String(error)}`); + } + } + fs.writeFileSync(path.join(scripts, "launch.json"), `${JSON.stringify({ + "appId": config.steam?.appId, depotId, "ready": !missing.length, + "requiredPlatforms": members, missing, "launches": launches + }, null, 2)}\n`); + if (missing.length) { + pending.push(`Depot ${depotId}: ${missing.join("; ")}`); + console.log(`Shared Steam depot ${depotId}: waiting for all OS packages. See ${path.join(scripts, "launch.json")}`); + continue; + } + fs.writeFileSync(path.join(scripts, "depot_build.vdf"), + `"DepotBuild"\n{\n "DepotID" "${depotId}"\n${mappings.join("\n")}\n "FileExclusion" "steam_appid.txt"\n "FileExclusion" "*.pdb"\n "FileExclusion" ".DS_Store"\n}\n`); + const contentRoot = path.relative(scripts, steamRoot); + for (const preview of [false, true]) { + fs.writeFileSync(path.join(scripts, preview ? "app_preview.vdf" : "app_build.vdf"), + `"AppBuild"\n{\n "AppID" "${config.steam?.appId}"\n "Desc" ${quote(`Shared depot ${depotId}: ${members.join(", ")} ${version}`)}\n "ContentRoot" ${quote(contentRoot)}\n "BuildOutput" "cache"\n "Preview" "${preview ? "1" : "0"}"\n "Depots"\n {\n "${depotId}" "depot_build.vdf"\n }\n}\n`); + } + console.log(`Shared Steam depot ready: ${scripts}`); + } + return pending; +}; diff --git a/src/tool-packages.ts b/src/tool-packages.ts new file mode 100644 index 0000000..3e65f88 --- /dev/null +++ b/src/tool-packages.ts @@ -0,0 +1,78 @@ +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { spawn } from "node:child_process"; + +// Keep native SDKs together and pin tools independently of the game's dependencies. +const packages = { + "electron": { "@electron/packager": "20.3.0" }, + "capacitor": { + "@capacitor/cli": "8.5.2", "@capacitor/core": "8.5.2", + "@capacitor/ios": "8.5.2", "@capacitor/android": "8.5.2" + } +}; +type Tool = keyof typeof packages; +const pending = new Map>>(); + +/** Launch npm's npx script with Node, avoiding cmd.exe quoting on Windows. */ +const resolveNpxCli = (): string => { + const candidates = [ + ...process.env.npm_execpath ? [path.join(path.dirname(process.env.npm_execpath), "npx-cli.js")] : [], + path.join(path.dirname(process.execPath), "node_modules/npm/bin/npx-cli.js"), + ...(process.env.PATH ?? "").split(path.delimiter).flatMap((dir) => [ + path.join(dir, "npx"), path.join(dir, "node_modules/npm/bin/npx-cli.js") + ]) + ]; + for (const file of candidates) { + if (fs.statSync(file, { "throwIfNoEntry": false })?.isFile()) { + const resolved = fs.realpathSync(file); + if (path.basename(resolved) === "npx-cli.js") { + return resolved; + } + } + } + throw new Error("npm/npx is required to download build tools. Install Node.js with npm and add it to PATH."); +}; + +const acquire = async (tool: Tool): Promise> => { + const cli = resolveNpxCli(); + const dir = fs.mkdtempSync(path.join(os.tmpdir(), "next2d-tools-")); + const result = path.join(dir, "packages.json"); + const specs = Object.entries(packages[tool]).map(([name, version]) => `--package=${name}@${version}`); + try { + console.log(`Preparing ${tool} tools via npx (${specs.map((spec) => spec.slice(10)).join(", ")})`); + await new Promise((resolve, reject) => { + const child = spawn(process.execPath, [cli, "--yes", ...specs, "--call", + "node --input-type=module -e \"import(process.env.NEXT2D_TOOL_RESOLVER)\"" + ], { + // A neutral cwd prevents project dependencies and npm hooks influencing tool acquisition. + "cwd": dir, "stdio": "inherit", + "env": { + ...process.env, + "NEXT2D_TOOL_RESOLVER": new URL("./resolve-tool-packages.js", import.meta.url).href, + "NEXT2D_TOOL_PACKAGES": JSON.stringify(packages[tool]), + "NEXT2D_TOOL_RESULT": result + } + }); + child.once("error", reject); + child.once("close", (code, signal) => code === 0 ? resolve() + : reject(new Error(`npx could not prepare ${tool} tools (${signal || code}). Check npm connectivity/cache and retry.`))); + }); + return JSON.parse(fs.readFileSync(result, "utf8")); + } finally { + fs.rmSync(dir, { "recursive": true, "force": true }); + } +}; + +/** Download only on first use; npm retains the packages after the temporary request is removed. */ +export const resolveToolPackages = (tool: Tool): Promise> => { + let request = pending.get(tool); + if (!request) { + request = acquire(tool).catch((error) => { + pending.delete(tool); + throw error; + }); + pending.set(tool, request); + } + return request; +}; diff --git a/src/web.ts b/src/web.ts index 504768d..7bb0a84 100644 --- a/src/web.ts +++ b/src/web.ts @@ -1,7 +1,8 @@ // Web ビルド: vite 設定の読み込みと HTML/JavaScript の書き出し。 -import pc from "picocolors"; +import pc from "./colors.js"; import fs from "fs"; -import { loadConfigFromFile } from "vite"; +import path from "node:path"; +import { loadProjectVite } from "./project-vite.js"; import { ctx } from "./context.js"; import { $spawn } from "./utils.js"; @@ -31,6 +32,7 @@ export const loadConfig = async (): Promise => const ext: string = fs.existsSync(`${process.cwd()}/vite.config.ts`) ? "ts" : "js"; + const { loadConfigFromFile } = await loadProjectVite(); const config = await loadConfigFromFile( { "command": "build", @@ -41,8 +43,8 @@ export const loadConfig = async (): Promise => // update config ctx.configObject = config; - ctx.outDir = ctx.configObject.config?.build?.outDir || "dist"; - ctx.buildDir = `${process.cwd()}/${ctx.outDir}/${ctx.platformDir}/${ctx.environment}`; + ctx.outDir = ctx.configObject?.config.build?.outDir || "dist"; + ctx.buildDir = path.resolve(ctx.outDir, ctx.platformDir, ctx.environment); if (!fs.existsSync(`${ctx.buildDir}`)) { fs.mkdirSync(`${ctx.buildDir}`, { "recursive": true }); @@ -67,10 +69,12 @@ export const buildWeb = (): Promise => "@next2d/vite-plugin-next2d-auto-loader" ], { "stdio": "inherit" }); + stream.once("error", reject); stream.on("close", (code: number): void => { if (code !== 0) { reject("vite plugin command failed."); + return; } const stream = $spawn("npx", [ @@ -80,10 +84,12 @@ export const buildWeb = (): Promise => "build" ], { "stdio": "inherit" }); + stream.once("error", reject); stream.on("close", (code: number): void => { if (code !== 0) { reject("Export of `HTML` and `JavaScript` failed."); + return; } console.log(); diff --git a/src/xbox.ts b/src/xbox.ts index b338148..bd94371 100644 --- a/src/xbox.ts +++ b/src/xbox.ts @@ -1,12 +1,12 @@ // Xbox (GDK ネイティブ) ビルド。V8 に Next2D の JS を載せ、Dawn(WebGPU/D3D12)で // 描画する C++ ホストを、テンプレートのスキャフォールド → 資材配置 → pak 埋め込み → // CMake/GDK ビルドの順で書き出す。 -import pc from "picocolors"; +import pc from "./colors.js"; import fs from "fs"; import os from "os"; import path from "path"; import cp from "child_process"; -import { minifySync } from "vite"; +import { loadProjectVite } from "./project-vite.js"; import { ctx } from "./context.js"; import { getTemplateDir } from "./utils.js"; import { @@ -208,12 +208,18 @@ export const renderAssetsRc = (pakAbsPath: string): string => * @method * @public */ -export const minifyJs = (name: string, code: string): string => +export const minifyJs = async (name: string, code: string): Promise => { try { - const result = minifySync(name, code); + const vite = await loadProjectVite(); + if (typeof vite.minifySync !== "function") { + // Vite 7 exposes esbuild rather than the Oxc minifier used by Vite 8. + const result = await vite.transformWithEsbuild(code, name, { "minify": true, "legalComments": "none" }); + return result.code; + } + const result = vite.minifySync(name, code); if (result.errors && result.errors.length > 0) { - const msg = (result.errors[0] as any)?.message ?? String(result.errors[0]); + const msg = result.errors[0]?.message ?? String(result.errors[0]); console.log(pc.yellow(`Xbox: minify skipped for ${name} (${msg}); embedding as-is.`)); return code; } @@ -240,74 +246,70 @@ export const minifyJs = (name: string, code: string): string => * @method * @private */ -const embedXboxAssets = (): Promise => +const embedXboxAssets = async (): Promise => { - return new Promise((resolve, reject): void => - { - const xboxDir: string = `${process.cwd()}/${XBOX_DIR_NAME}`; - const pakPath: string = `${xboxDir}/assets.pak`; - const rcPath: string = `${xboxDir}/assets.rc`; + const xboxDir: string = `${process.cwd()}/${XBOX_DIR_NAME}`; + const pakPath: string = `${xboxDir}/assets.pak`; + const rcPath: string = `${xboxDir}/assets.rc`; - try { - // 収集: assets/app 一式 (キーは app 基準) + host スクリプト (js/ 基準)。 - const entries: [string, string][] = []; - entries.push(...walkFiles(`${xboxDir}/assets/app`, "")); - const bootstrap: string = `${xboxDir}/js/bootstrap.js`; - if (fs.existsSync(bootstrap)) { - entries.push(["js/bootstrap.js", bootstrap]); - } - const selftest: string = `${xboxDir}/js/selftest.js`; - if (fs.existsSync(selftest)) { - entries.push(["js/selftest.js", selftest]); - } + try { + // 収集: assets/app 一式 (キーは app 基準) + host スクリプト (js/ 基準)。 + const entries: [string, string][] = []; + entries.push(...walkFiles(`${xboxDir}/assets/app`, "")); + const bootstrap: string = `${xboxDir}/js/bootstrap.js`; + if (fs.existsSync(bootstrap)) { + entries.push(["js/bootstrap.js", bootstrap]); + } + const selftest: string = `${xboxDir}/js/selftest.js`; + if (fs.existsSync(selftest)) { + entries.push(["js/selftest.js", selftest]); + } - if (entries.length === 0) { - return reject("No Xbox assets found to embed (assets/app is empty)."); - } + if (entries.length === 0) { + throw new Error("No Xbox assets found to embed (assets/app is empty)."); + } - // (key, データ) を読み込み、pak バイナリへ直列化する。 - // js/ のホストスクリプト(bootstrap.js/selftest.js)は minify + 難読化する。 - // assets/app の JS は vite が本番ビルドで minify 済みのためそのまま。 - let minified = 0; - const pakEntries: [string, Buffer][] = entries.map( - ([key, abs]): [string, Buffer] => { - if (key.startsWith("js/") && key.endsWith(".js")) { - const src = fs.readFileSync(abs, { "encoding": "utf8" }); - const out = minifyJs(key, src); - if (out.length < src.length) { - ++minified; - } - return [key, Buffer.from(out, "utf8")]; + // (key, データ) を読み込み、pak バイナリへ直列化する。 + // js/ のホストスクリプト(bootstrap.js/selftest.js)は minify + 難読化する。 + // assets/app の JS は vite が本番ビルドで minify 済みのためそのまま。 + let minified = 0; + const pakEntries: [string, Buffer][] = await Promise.all(entries.map( + async ([key, abs]): Promise<[string, Buffer]> => { + if (key.startsWith("js/") && key.endsWith(".js")) { + const src = fs.readFileSync(abs, { "encoding": "utf8" }); + const out = await minifyJs(key, src); + if (out.length < src.length) { + ++minified; } - return [key, fs.readFileSync(abs)]; + return [key, Buffer.from(out, "utf8")]; } - ); - const pak: Buffer = buildPak(pakEntries); - if (minified > 0) { - console.log(pc.green(`Minified ${minified} host script(s) before embedding.`)); + return [key, fs.readFileSync(abs)]; } - fs.writeFileSync(pakPath, pak); + )); + const pak: Buffer = buildPak(pakEntries); + if (minified > 0) { + console.log(pc.green(`Minified ${minified} host script(s) before embedding.`)); + } + fs.writeFileSync(pakPath, pak); - // rc.exe が assets.pak を RCDATA "N2DASSETS" として取り込む .rc を生成する。 - fs.writeFileSync(rcPath, renderAssetsRc(path.resolve(pakPath)), "utf8"); + // rc.exe が assets.pak を RCDATA "N2DASSETS" として取り込む .rc を生成する。 + fs.writeFileSync(rcPath, renderAssetsRc(path.resolve(pakPath)), "utf8"); - console.log(pc.green( - `Embedded ${entries.length} Xbox asset file(s) into assets.pak ` + console.log(pc.green( + `Embedded ${entries.length} Xbox asset file(s) into assets.pak ` + `(${(pak.length / 1024 / 1024).toFixed(2)} MB).` - )); + )); - // 埋め込み済みの平文 `assets/`・`js/` は書き出し一覧から除外する。 - // これらは assets.pak (=exe 内 RCDATA) に格納済みで、CMake も埋め込みモードでは - // exe 隣へステージしないため、xbox/ 直下に残しても不要かつ平文流出になる。 - fs.rmSync(`${xboxDir}/assets`, { "recursive": true, "force": true }); - fs.rmSync(`${xboxDir}/js`, { "recursive": true, "force": true }); - console.log(pc.green("Excluded plaintext `assets/` and `js/` from the export (embedded in exe).")); + // 埋め込み済みの平文 `assets/`・`js/` は書き出し一覧から除外する。 + // これらは assets.pak (=exe 内 RCDATA) に格納済みで、CMake も埋め込みモードでは + // exe 隣へステージしないため、xbox/ 直下に残しても不要かつ平文流出になる。 + fs.rmSync(`${xboxDir}/assets`, { "recursive": true, "force": true }); + fs.rmSync(`${xboxDir}/js`, { "recursive": true, "force": true }); + console.log(pc.green("Excluded plaintext `assets/` and `js/` from the export (embedded in exe).")); - resolve(); - } catch (error) { - reject(`Failed to embed Xbox assets. ${error}`); - } - }); + } catch (error) { + throw new Error(`Failed to embed Xbox assets. ${error}`); + } }; /** diff --git a/templates/electron/entitlements.plist b/templates/electron/entitlements.plist new file mode 100644 index 0000000..f795eb2 --- /dev/null +++ b/templates/electron/entitlements.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/templates/electron/icons/icon.icns b/templates/electron/icons/icon.icns new file mode 100644 index 0000000..dc30a34 Binary files /dev/null and b/templates/electron/icons/icon.icns differ diff --git a/templates/electron/icons/icon.ico b/templates/electron/icons/icon.ico new file mode 100644 index 0000000..3d07c9d Binary files /dev/null and b/templates/electron/icons/icon.ico differ diff --git a/templates/electron/icons/icon.png b/templates/electron/icons/icon.png new file mode 100644 index 0000000..552ab20 Binary files /dev/null and b/templates/electron/icons/icon.png differ diff --git a/templates/electron/index.js b/templates/electron/index.js new file mode 100644 index 0000000..3711df7 --- /dev/null +++ b/templates/electron/index.js @@ -0,0 +1,95 @@ +const { app, BrowserWindow, Menu, net, protocol, screen, session } = require("electron"); +const path = require("node:path"); +const fs = require("node:fs"); +const { pathToFileURL } = require("node:url"); +const { resolveAssetPath, CSP } = require("./local-assets.cjs"); +const config = require("./runtime-config.json"); +// Keep saves in a stable user directory even if the visible game name changes. +app.setName(config.appName); +app.setPath("userData", path.join(app.getPath("appData"), config.appId)); +const assetRoot = app.isPackaged + ? path.join(process.resourcesPath, "resources") + : path.join(__dirname, "resources"); + +// A fixed secure origin supports fetch, module scripts, workers and localStorage. +protocol.registerSchemesAsPrivileged([{ + scheme: "next2d", + privileges: { standard: true, secure: true, supportFetchAPI: true, corsEnabled: true, stream: true } +}]); + +const startURL = "next2d://game/index.html"; +let mainWindow; +const createWindow = async () => { + const { width, height } = screen.getPrimaryDisplay().workAreaSize; + mainWindow = new BrowserWindow({ + width: Math.min(config.window.width, width), + height: Math.min(config.window.height, height), + title: config.appName, + fullscreen: config.window.fullscreen, + ...(config.icon ? { icon: path.join(assetRoot, config.icon) } : {}), + useContentSize: true, + backgroundColor: "#000000", + autoHideMenuBar: true, + show: false, + webPreferences: { nodeIntegration: false, contextIsolation: true, sandbox: true } + }); + mainWindow.webContents.setWindowOpenHandler(() => ({ action: "deny" })); + mainWindow.webContents.on("will-navigate", (event, url) => { + if (!resolveAssetPath(assetRoot, url)) { + event.preventDefault(); + } + }); + mainWindow.webContents.on("before-input-event", (event, input) => { + if (input.type !== "keyDown") { + return; + } + if (input.key === "F11" || (input.alt && input.key === "Enter")) { + mainWindow.setFullScreen(!mainWindow.isFullScreen()); + event.preventDefault(); + } else if (input.key === "Escape" && mainWindow.isFullScreen()) { + mainWindow.setFullScreen(false); + event.preventDefault(); + } + }); + mainWindow.webContents.on("render-process-gone", (_event, details) => { + console.error("Renderer exited:", details.reason); + app.exit(1); + }); + mainWindow.once("ready-to-show", () => mainWindow.show()); + await mainWindow.loadURL(startURL); +}; + +app.whenReady().then(async () => { + Menu.setApplicationMenu(process.platform === "darwin" ? Menu.buildFromTemplate([ + { role: "appMenu" }, { role: "editMenu" }, { role: "windowMenu" } + ]) : null); + session.defaultSession.setPermissionRequestHandler((_contents, permission, callback) => { + callback(permission === "fullscreen"); + }); + session.defaultSession.setPermissionCheckHandler((_contents, permission) => permission === "fullscreen"); + protocol.handle("next2d", async (request) => { + let asset = resolveAssetPath(assetRoot, request.url); + if (!asset || request.method !== "GET") { + return new Response("Not found", { status: 404 }); + } + // Framework SPA routes use history.pushState (e.g. /home); reload the entry. + if (!path.extname(asset) && !fs.existsSync(asset)) { + asset = path.join(assetRoot, "index.html"); + } + try { + const response = await net.fetch(pathToFileURL(asset).href); + const headers = new Headers(response.headers); + headers.set("Content-Security-Policy", CSP); + return new Response(response.body, { status: response.status, headers }); + } catch { + return new Response("Not found", { status: 404 }); + } + }); + await createWindow(); +}).catch((error) => { + console.error(error); + app.exit(1); +}); + +// Closing the game must stop Steam's "Running" status, including on macOS. +app.on("window-all-closed", () => app.quit()); diff --git a/templates/electron/local-assets.cjs b/templates/electron/local-assets.cjs new file mode 100644 index 0000000..4ad8810 --- /dev/null +++ b/templates/electron/local-assets.cjs @@ -0,0 +1,24 @@ +const path = require("node:path"); + +const CSP = "default-src 'self' data: blob:; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob: data:; style-src 'self' 'unsafe-inline'; object-src 'none'; base-uri 'none'"; +const resolveAssetPath = (root, requestURL) => { + try { + const url = new URL(requestURL); + if (url.protocol !== "next2d:" || url.host !== "game" || url.username || url.password) { + return null; + } + const name = decodeURIComponent(url.pathname); + if (name.includes("\0") || name.includes("\\")) { + return null; + } + const file = path.resolve(root, `.${name === "/" ? "/index.html" : name}`); + const relative = path.relative(root, file); + if (!relative || relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) { + return null; + } + return file; + } catch { + return null; + } +}; +module.exports = { CSP, resolveAssetPath }; diff --git a/templates/electron/package.json b/templates/electron/package.json new file mode 100644 index 0000000..adae14e --- /dev/null +++ b/templates/electron/package.json @@ -0,0 +1,11 @@ +{ + "name": "next2d-game", + "version": "1.0.0", + "description": "Next2D desktop game", + "private": true, + "type": "commonjs", + "main": "index.js", + "devDependencies": { + "electron": "44.4.3" + } +} diff --git a/templates/xbox/src/platform/StbTextRasterizer.cpp b/templates/xbox/src/platform/StbTextRasterizer.cpp index 6f5fc72..75b0167 100644 --- a/templates/xbox/src/platform/StbTextRasterizer.cpp +++ b/templates/xbox/src/platform/StbTextRasterizer.cpp @@ -192,16 +192,18 @@ bool ComputeLayout(const std::string& css_font, const std::wstring& text, Layout stbtt_GetFontVMetrics(&lo.font->info, &lo.ascent, &lo.descent, &line_gap); lo.cps = ToCodepoints(text); + // Keep layout arithmetic in double; stb's bitmap API still takes float. + const double scale = lo.scale; double x = 0; for (size_t i = 0; i < lo.cps.size(); ++i) { int advance = 0, lsb = 0; stbtt_GetCodepointHMetrics(&lo.font->info, static_cast(lo.cps[i]), &advance, &lsb); - x += advance * lo.scale; + x += advance * scale; if (i + 1 < lo.cps.size()) { x += stbtt_GetCodepointKernAdvance( &lo.font->info, static_cast(lo.cps[i]), - static_cast(lo.cps[i + 1])) * lo.scale; + static_cast(lo.cps[i + 1])) * scale; } } lo.width = x; @@ -239,9 +241,10 @@ bool MeasureText(const std::string& css_font, const std::wstring& text, if (!ComputeLayout(css_font, text, lo)) { return false; } + const double scale = lo.scale; out.width = lo.width; - out.ascent = lo.ascent * lo.scale; - out.descent = -lo.descent * lo.scale; // stbtt の descent は負値 + out.ascent = lo.ascent * scale; + out.descent = -static_cast(lo.descent) * scale; // stbtt の descent は負値 return true; } @@ -256,8 +259,9 @@ bool RasterizeText(const std::string& css_font, const std::wstring& text, return false; } - const double ascent_px = lo.ascent * lo.scale; - const double descent_px = -lo.descent * lo.scale; + const double scale = lo.scale; + const double ascent_px = lo.ascent * scale; + const double descent_px = -static_cast(lo.descent) * scale; const int width = std::max(1, static_cast(std::ceil(lo.width)) + 2); const int height = std::max(1, static_cast(std::ceil(ascent_px + descent_px)) + 2); const int baseline = static_cast(std::ceil(ascent_px)) + 1; @@ -272,7 +276,7 @@ bool RasterizeText(const std::string& css_font, const std::wstring& text, int x0 = 0, y0 = 0, x1 = 0, y1 = 0; const float shift_x = - static_cast(pen_x + lsb * lo.scale - std::floor(pen_x + lsb * lo.scale)); + static_cast(pen_x + lsb * scale - std::floor(pen_x + lsb * scale)); stbtt_GetCodepointBitmapBoxSubpixel( &lo.font->info, cp, lo.scale, lo.scale, shift_x, 0, &x0, &y0, &x1, &y1); @@ -284,7 +288,7 @@ bool RasterizeText(const std::string& css_font, const std::wstring& text, &lo.font->info, glyph.data(), gw, gh, gw, lo.scale, lo.scale, shift_x, 0, cp); - const int dst_x = static_cast(std::floor(pen_x + lsb * lo.scale)); + const int dst_x = static_cast(std::floor(pen_x + lsb * scale)); const int dst_y = baseline + y0; for (int yy = 0; yy < gh; ++yy) { const int py = dst_y + yy; @@ -298,10 +302,10 @@ bool RasterizeText(const std::string& css_font, const std::wstring& text, } } - pen_x += advance * lo.scale; + pen_x += advance * scale; if (i + 1 < lo.cps.size()) { pen_x += stbtt_GetCodepointKernAdvance( - &lo.font->info, cp, static_cast(lo.cps[i + 1])) * lo.scale; + &lo.font->info, cp, static_cast(lo.cps[i + 1])) * scale; } } diff --git a/templates/xbox/tests/check_local.sh b/templates/xbox/tests/check_local.sh index ad5c2d4..63fbe6e 100755 --- a/templates/xbox/tests/check_local.sh +++ b/templates/xbox/tests/check_local.sh @@ -2,7 +2,8 @@ # macOS / Linux で Windows 実機なしに実行できる検証をまとめて回す。 # 1. RasterCore 単体テスト (実行) # 2. RasterCore 単体テスト (ASan/UBSan) -# 3. V8 依存ソースの構文チェック (実 V8 ヘッダに対して。Windows API 非依存の12ファイル) +# 3. stb 境界値・デコード回帰テスト (通常 + ASan/UBSan) +# 4. V8 依存ソースの構文チェック (実 V8 ヘッダに対して) # # 使い方: # tests/check_local.sh [V8_INCLUDE_DIR] @@ -13,16 +14,23 @@ cd "$(dirname "$0")/.." V8_TAG="13.7.152.19" V8INC="${1:-}" -echo "== 1/3 RasterCore unit tests ==" +echo "== 1/4 RasterCore unit tests ==" c++ -std=c++17 -Wall -Wextra -O1 -o /tmp/next2d_raster_test tests/raster_test.cpp /tmp/next2d_raster_test -echo "== 2/3 RasterCore unit tests (ASan/UBSan) ==" +echo "== 2/4 RasterCore unit tests (ASan/UBSan) ==" c++ -std=c++17 -g -fsanitize=address,undefined -fno-omit-frame-pointer \ -o /tmp/next2d_raster_test_asan tests/raster_test.cpp /tmp/next2d_raster_test_asan -echo "== 3/3 V8-dependent sources syntax check (V8 ${V8_TAG}) ==" +echo "== 3/4 stb safety regression tests ==" +c++ -std=c++17 -O1 -o /tmp/next2d_stb_safety_test tests/stb_safety_test.cpp +/tmp/next2d_stb_safety_test +c++ -std=c++17 -g -fsanitize=address,undefined -fno-omit-frame-pointer \ + -o /tmp/next2d_stb_safety_test_asan tests/stb_safety_test.cpp +/tmp/next2d_stb_safety_test_asan + +echo "== 4/4 V8-dependent sources syntax check (V8 ${V8_TAG}) ==" if [ -z "${V8INC}" ]; then if [ ! -d ".v8_headers/include" ]; then git clone --depth 1 --branch "${V8_TAG}" --filter=blob:none --sparse \ diff --git a/templates/xbox/tests/stb_safety_test.cpp b/templates/xbox/tests/stb_safety_test.cpp new file mode 100644 index 0000000..00d0b9d --- /dev/null +++ b/templates/xbox/tests/stb_safety_test.cpp @@ -0,0 +1,126 @@ +// Regression tests for local stb patches. No Windows SDK, V8 or external assets. +#include +#include +#include +#include + +// Record allocation attempts without allocating huge buffers in boundary tests. +static size_t last_allocation = 0; +static void* TestMalloc(size_t size) +{ + last_allocation = size; + return size > 64 * 1024 * 1024 ? nullptr : std::malloc(size); +} +static void* TestRealloc(void* data, size_t size) +{ + last_allocation = size; + return size > 64 * 1024 * 1024 ? nullptr : std::realloc(data, size); +} + +#define STBI_MALLOC TestMalloc +#define STBI_REALLOC TestRealloc +#define STBI_FREE std::free +#define STBI_NO_STDIO +#define STB_IMAGE_IMPLEMENTATION +#include "../third_party/stb_image.h" + +#define STB_VORBIS_NO_STDIO +#define STB_VORBIS_NO_PUSHDATA_API +#include "../third_party/stb_vorbis.c" + +static int failures = 0; +static int checks = 0; +#define EXPECT(condition) do { ++checks; if (!(condition)) { \ + ++failures; std::printf("not ok - line %d: %s\n", __LINE__, #condition); } } while (0) + +static void Test16BitConversion() +{ + auto* pixel = static_cast(std::malloc(3 * sizeof(stbi__uint16))); + pixel[0] = 123; pixel[1] = 456; pixel[2] = 789; + auto* rgba = stbi__convert_format16(pixel, 3, 4, 1, 1); + EXPECT(rgba != nullptr); + if (rgba) { + EXPECT(rgba[0] == 123 && rgba[1] == 456 && rgba[2] == 789 && rgba[3] == 65535); + std::free(rgba); + } + + // The original unsigned product wraps to zero for these dimensions. + // Conversion must reject the size before allocating or reading input pixels. + const unsigned int dimensions[][2] = {{65536, 8192}, {UINT_MAX, 1}, {1, UINT_MAX}}; + for (const auto& size : dimensions) { + pixel = static_cast(std::malloc(3 * sizeof(stbi__uint16))); + last_allocation = 0; + rgba = stbi__convert_format16(pixel, 3, 4, size[0], size[1]); + EXPECT(rgba == nullptr); + EXPECT(last_allocation == 0); + std::free(rgba); + } +} + +static void TestAnimatedGif() +{ + // Original fixture: 1x1, black/red palette. Frame 2 restores frame 1; + // transparent frame 3 must therefore show red, not read before the buffer. + std::vector gif = { + 'G', 'I', 'F', '8', '9', 'a', 1, 0, 1, 0, 0x80, 0, 0, + 0, 0, 0, 255, 0, 0 + }; + const stbi_uc controls[] = {4, 12, 5}; + const stbi_uc pixels[] = {0x4c, 0x44, 0x44}; + for (int i = 0; i < 3; ++i) { + gif.insert(gif.end(), {0x21, 0xf9, 4, controls[i], 1, 0, 0, 0, + 0x2c, 0, 0, 0, 0, 1, 0, 1, 0, 0, 2, 2, pixels[i], 1, 0}); + } + gif.push_back(0x3b); + int* delays = nullptr; + int width = 0, height = 0, frames = 0, components = 0; + stbi_uc* rgba = stbi_load_gif_from_memory(gif.data(), static_cast(gif.size()), + &delays, &width, &height, &frames, &components, 4); + EXPECT(rgba != nullptr); + EXPECT(width == 1 && height == 1 && frames == 3 && components == 4); + if (rgba && frames == 3) { + EXPECT(rgba[0] == 255 && rgba[1] == 0 && rgba[2] == 0 && rgba[3] == 255); + EXPECT(rgba[4] == 0 && rgba[5] == 0 && rgba[6] == 0 && rgba[7] == 255); + EXPECT(rgba[8] == 255 && rgba[9] == 0 && rgba[10] == 0 && rgba[11] == 255); + } + EXPECT(delays != nullptr); + if (delays && frames == 3) EXPECT(delays[0] == 10 && delays[1] == 10 && delays[2] == 10); + stbi_image_free(rgba); + stbi_image_free(delays); + + // Oversized canvas is rejected before any pixel buffer is allocated. + gif[6] = gif[7] = gif[8] = gif[9] = 255; + last_allocation = 0; + rgba = stbi_load_gif_from_memory(gif.data(), static_cast(gif.size()), + &delays, &width, &height, &frames, &components, 4); + EXPECT(rgba == nullptr); + EXPECT(last_allocation == 0); + stbi_image_free(rgba); + stbi_image_free(delays); +} + +static void TestVorbisSeekBounds() +{ + unsigned char bytes[16] = {}; + stb_vorbis decoder = {}; + decoder.stream_start = bytes; + decoder.stream_end = bytes + sizeof(bytes); + for (unsigned int offset : {0U, 15U, 16U, 17U, UINT_MAX, 0U}) { + const bool valid = offset < sizeof(bytes); + EXPECT(set_file_offset(&decoder, offset) == static_cast(valid)); + EXPECT(decoder.eof == static_cast(!valid)); + EXPECT(decoder.stream == (valid ? bytes + offset : decoder.stream_end)); + } + decoder.stream_end = decoder.stream_start; + EXPECT(set_file_offset(&decoder, 0) == 0); + EXPECT(decoder.eof == 1 && decoder.stream == decoder.stream_end); +} + +int main() +{ + Test16BitConversion(); + TestAnimatedGif(); + TestVorbisSeekBounds(); + std::printf("stb safety: %d checks, %d failures\n", checks, failures); + return failures ? 1 : 0; +} diff --git a/templates/xbox/third_party/LICENSES.md b/templates/xbox/third_party/LICENSES.md index 9b12d8b..21eaee0 100644 --- a/templates/xbox/third_party/LICENSES.md +++ b/templates/xbox/third_party/LICENSES.md @@ -12,3 +12,18 @@ | dr_wav.h | https://github.com/mackron/dr_libs | public domain (Unlicense) / MIT-0 のデュアル | いずれも各ファイル末尾に原文のライセンス条文が含まれる。 + +## ローカル修正 / Local patches + +同梱の stb には以下の修正を適用している。更新時は再適用の要否を確認し、 +`tests/stb_safety_test.cpp` と既存のプラットフォームテストを実行する。 + +The vendored stb files include these local patches. When updating upstream code, +check whether they are still needed and run `tests/stb_safety_test.cpp` and the +existing platform tests. + +| ファイル / File | 修正 / Patch | +|---|---| +| stb_image.h | メモリサイズを乗算前に拡張し、16bit変換・GIFフレーム追加時のオーバーフローを検証。GIFの過去フレーム参照をバッファ内に修正。 / Widen operands before size multiplication, validate overflow in 16-bit conversion and GIF frame growth, and keep GIF previous-frame references inside the buffer. | +| stb_truetype.h | ビットマップの確保・初期化サイズを `size_t` で乗算。 / Multiply bitmap allocation and initialization sizes in `size_t`. | +| stb_vorbis.c | ポインタ加算前に入力サイズとシーク位置を比較。 / Check seek offsets against the input size before pointer arithmetic. | diff --git a/templates/xbox/third_party/stb_image.h b/templates/xbox/third_party/stb_image.h index 9eedabe..a5c6456 100644 --- a/templates/xbox/third_party/stb_image.h +++ b/templates/xbox/third_party/stb_image.h @@ -1817,7 +1817,8 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r if (req_comp == img_n) return data; STBI_ASSERT(req_comp >= 1 && req_comp <= 4); - good = (stbi__uint16 *) stbi__malloc(req_comp * x * y * 2); + good = (x > INT_MAX || y > INT_MAX) ? NULL : + (stbi__uint16 *) stbi__malloc_mad4(req_comp, (int) x, (int) y, 2, 0); if (good == NULL) { STBI_FREE(data); return (stbi__uint16 *) stbi__errpuc("outofmem", "Out of memory"); @@ -4821,7 +4822,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r stbi__create_png_alpha_expand8(dest, dest, x, img_n); } else if (depth == 8) { if (img_n == out_n) - memcpy(dest, cur, x*img_n); + memcpy(dest, cur, (size_t) x*img_n); else stbi__create_png_alpha_expand8(dest, cur, x, img_n); } else if (depth == 16) { @@ -6201,7 +6202,7 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req out = (stbi_uc *) stbi__malloc_mad3(8, w, h, 0); ri->bits_per_channel = 16; } else - out = (stbi_uc *) stbi__malloc(4 * w*h); + out = (stbi_uc *) stbi__malloc_mad3(4, w, h, 0); if (!out) return stbi__errpuc("outofmem", "Out of memory"); pixelCount = w*h; @@ -6524,7 +6525,7 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c // intermediate buffer is RGBA result = (stbi_uc *) stbi__malloc_mad3(x, y, 4, 0); if (!result) return stbi__errpuc("outofmem", "Out of memory"); - memset(result, 0xff, x*y*4); + memset(result, 0xff, (size_t) x*y*4); if (!stbi__pic_load_core(s,x,y,comp, result)) { STBI_FREE(result); @@ -6833,11 +6834,11 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i } // background is what out is after the undoing of the previou frame; - memcpy( g->background, g->out, 4 * g->w * g->h ); + memcpy( g->background, g->out, (size_t) 4 * g->w * g->h ); } // clear my history; - memset( g->history, 0x00, g->w * g->h ); // pixels that were affected previous frame + memset( g->history, 0x00, (size_t) g->w * g->h ); // pixels that were affected previous frame for (;;) { int tag = stbi__get8(s); @@ -6987,11 +6988,15 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, if (u) { *x = g.w; *y = g.h; - ++layers; stride = g.w * g.h * 4; + // Keep the frame count, byte offsets and allocator sizes representable. + if (layers == INT_MAX || !stbi__mul2sizes_valid(layers + 1, stride) || + !stbi__mul2sizes_valid(layers + 1, sizeof(int))) + return stbi__load_gif_main_outofmem(&g, out, delays); + ++layers; if (out) { - void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride ); + void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, (size_t) layers * stride ); if (!tmp) return stbi__load_gif_main_outofmem(&g, out, delays); else { @@ -7007,7 +7012,7 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, delays_size = layers * sizeof(int); } } else { - out = (stbi_uc*)stbi__malloc( layers * stride ); + out = (stbi_uc*)stbi__malloc( (size_t) layers * stride ); if (!out) return stbi__load_gif_main_outofmem(&g, out, delays); out_size = layers * stride; @@ -7020,7 +7025,7 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y, } memcpy( out + ((layers - 1) * stride), u, stride ); if (layers >= 2) { - two_back = out - 2 * stride; + two_back = out + (layers - 2) * stride; } if (delays) { diff --git a/templates/xbox/third_party/stb_truetype.h b/templates/xbox/third_party/stb_truetype.h index 90a5c2e..02b3e7e 100644 --- a/templates/xbox/third_party/stb_truetype.h +++ b/templates/xbox/third_party/stb_truetype.h @@ -3739,7 +3739,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info if (yoff ) *yoff = iy0; if (gbm.w && gbm.h) { - gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); + gbm.pixels = (unsigned char *) STBTT_malloc((size_t) gbm.w * gbm.h, info->userdata); if (gbm.pixels) { gbm.stride = gbm.w; @@ -3822,7 +3822,7 @@ static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // fo f.userdata = NULL; if (!stbtt_InitFont(&f, data, offset)) return -1; - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + STBTT_memset(pixels, 0, (size_t) pw*ph); // background of 0 around pixels x=y=1; bottom_y = 1; @@ -3981,7 +3981,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); if (pixels) - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + STBTT_memset(pixels, 0, (size_t) pw*ph); // background of 0 around pixels return 1; } @@ -4610,7 +4610,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc float *precompute; stbtt_vertex *verts; int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); - data = (unsigned char *) STBTT_malloc(w * h, info->userdata); + data = (unsigned char *) STBTT_malloc((size_t) w * h, info->userdata); precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata); for (i=0,j=num_verts-1; i < num_verts; j=i++) { diff --git a/templates/xbox/third_party/stb_vorbis.c b/templates/xbox/third_party/stb_vorbis.c index 3e5c250..65afd96 100644 --- a/templates/xbox/third_party/stb_vorbis.c +++ b/templates/xbox/third_party/stb_vorbis.c @@ -1401,7 +1401,7 @@ static int set_file_offset(stb_vorbis *f, unsigned int loc) #endif f->eof = 0; if (USE_MEMORY(f)) { - if (f->stream_start + loc >= f->stream_end || f->stream_start + loc < f->stream_start) { + if (loc >= (size_t) (f->stream_end - f->stream_start)) { f->stream = f->stream_end; f->eof = 1; return 0; diff --git a/tests/cli.test.ts b/tests/cli.test.ts index f4d13b0..142ca66 100644 --- a/tests/cli.test.ts +++ b/tests/cli.test.ts @@ -55,3 +55,8 @@ test("SUPPORTED_PLATFORMS: 期待するプラットフォームを含む", () => } assert.equal(SUPPORTED_PLATFORMS.has("bogus"), false); }); + +test("parseArgv: Electron architecture and missing value", () => { + assert.equal(parseArgv(["--platform", "steam:macos", "--env", "prd", "--arch", "universal"]).arch, "universal"); + assert.equal(parseArgv(["--platform", "steam:linux", "--env", "prd", "--arch"]).hasHelp, true); +}); diff --git a/tests/electron.test.ts b/tests/electron.test.ts new file mode 100644 index 0000000..f5eb4b0 --- /dev/null +++ b/tests/electron.test.ts @@ -0,0 +1,244 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { createRequire } from "node:module"; +import { resolveElectronTarget } from "../dist/electron.js"; +import { withElectronHost, getElectronVersion } from "../dist/electron-host.js"; +import { readElectronConfig, createElectronPackagerOptions } from "../dist/electron-config.js"; +import { readSteamConfig, writeSteamMetadata } from "../dist/steam.js"; +const require = createRequire(import.meta.url); +const { resolveAssetPath } = require("../templates/electron/local-assets.cjs"); + +const fixture = (t) => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d electron ")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "test-game", version: "1.2.3" })); + return root; +}; + +test("Steam targets use darwin, universal macOS and x64 Windows/Linux", () => { + assert.deepEqual(resolveElectronTarget("steam:macos"), { platform: "darwin", arch: "universal" }); + assert.deepEqual(resolveElectronTarget("steam:windows"), { platform: "win32", arch: "x64" }); + assert.deepEqual(resolveElectronTarget("steam:linux"), { platform: "linux", arch: "x64" }); + assert.throws(() => resolveElectronTarget("steam:linux", "universal")); + assert.throws(() => resolveElectronTarget("steam:windows", "all")); + assert.throws(() => resolveElectronTarget("mas")); + const foreign = process.platform === "win32" ? "linux" : "windows"; + assert.throws(() => resolveElectronTarget(foreign, "", true)); +}); + +test("temporary host uses current metadata and assets without creating a game electron directory", async (t) => { + const root = fixture(t); + const source = path.join(root, "web"); + fs.mkdirSync(source); + fs.writeFileSync(path.join(source, "index.html"), "hello"); + const config = readElectronConfig(root); + let generated; + const result = await withElectronHost(root, source, config, async (dir) => { + generated = dir; + const pkg = JSON.parse(fs.readFileSync(path.join(dir, "package.json"), "utf8")); + assert.equal(pkg.version, "1.2.3"); + assert.equal(pkg.name, "test-game"); + assert.equal(pkg.dependencies, undefined); + assert.equal(pkg.devDependencies, undefined); + assert.equal(fs.readFileSync(path.join(dir, "resources/index.html"), "utf8"), "hello"); + const runtime = JSON.parse(fs.readFileSync(path.join(dir, "runtime-config.json"), "utf8")); + assert.equal(runtime.appId, config.appId); + assert.ok(fs.existsSync(path.join(dir, "resources", runtime.icon))); + assert.match(fs.readFileSync(path.join(dir, "index.js"), "utf8"), /sandbox: true/); + assert.equal(fs.existsSync(path.join(dir, "node_modules")), false); + const options = createElectronPackagerOptions(root, config, "windows", path.join(dir, "resources")); + assert.deepEqual(options.extraResource, [path.join(dir, "resources")]); + return "packaged"; + }); + assert.equal(result, "packaged"); + assert.equal(fs.existsSync(generated), false); + assert.equal(fs.existsSync(path.join(root, "electron")), false); + assert.match(getElectronVersion(), /^\d+\.\d+\.\d+$/); +}); + +test("temporary host is removed on failure and separate builds never reuse host files", async (t) => { + const root = fixture(t); + const config = readElectronConfig(root); + await assert.rejects(withElectronHost(root, root, config, async () => assert.fail("must not be called")), /entry point is missing/); + fs.writeFileSync(path.join(root, "index.html"), "hello"); + const generated = []; + await assert.rejects(withElectronHost(root, root, config, async (first) => { + generated.push(first); + return withElectronHost(root, root, config, async (second) => { + generated.push(second); + assert.notEqual(first, second); + assert.ok(fs.existsSync(first)); + throw new Error("packaging failed"); + }); + }), /packaging failed/); + for (const dir of generated) { + assert.equal(fs.existsSync(dir), false); + } + assert.deepEqual(fs.readdirSync(root).sort(), ["index.html", "package.json"]); +}); + +test("JSON metadata drives packaging; missing Depot IDs still allow export", (t) => { + const root = fixture(t); + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ + appId: "app.test.game", appName: "My Game", executableName: "my-game", + steam: { appId: 2409460, depots: { windows: null } } + })); + const config = readElectronConfig(root); + const options = createElectronPackagerOptions(root, config, "windows", path.join(root, "resources")); + assert.equal(options.name, "My Game"); + assert.equal(options.appBundleId, "app.test.game"); + assert.equal(options.executableName, "my-game"); + assert.deepEqual(readSteamConfig(config, "steam:windows"), { appId: "2409460", depotId: null }); +}); + +test("Electron host and Windows description prefer config and fall back to package metadata", async (t) => { + const root = fixture(t); + const web = path.join(root, "web"); + fs.mkdirSync(web); + fs.writeFileSync(path.join(web, "index.html"), "game"); + for (const [override, fallback, expected] of [ + ["Desktop description", "Package description", "Desktop description"], + [undefined, "Package description", "Package description"], + [null, "Package description", "Package description"], + ["", "Package description", ""], + [undefined, undefined, ""] + ]) { + fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "test-game", version: "1.2.3", description: fallback })); + const source = JSON.stringify({ description: override }); + fs.writeFileSync(path.join(root, "electron.config.json"), source); + const config = readElectronConfig(root); + await withElectronHost(root, web, config, async (dir) => { + assert.equal(JSON.parse(fs.readFileSync(path.join(dir, "package.json"))).description, expected); + assert.equal(createElectronPackagerOptions(root, config, "windows", web).win32metadata.FileDescription, expected); + }); + assert.equal(fs.readFileSync(path.join(root, "electron.config.json"), "utf8"), source); + } + fs.writeFileSync(path.join(root, "electron.config.json"), '{"description":123}'); + assert.throws(() => readElectronConfig(root), /description must be a string/); +}); + +test("invalid IDs, invalid icons and unsafe names fail", (t) => { + const root = fixture(t); + for (const input of [ + { steam: { appId: 0 } }, + { steam: { appId: null, depots: { windows: 123 } } }, + { icons: { windows: "missing.ico" } }, + { appName: "../escape" }, + { architectures: { linux: "universal" } }, + { macos: { notarize: true, sign: false } } + ]) { + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify(input)); + assert.throws(() => readElectronConfig(root)); + } +}); + +test("unassigned Steam IDs in templates allow local packaging", (t) => { + const root = fixture(t); + for (const appId of [null, undefined]) { + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ + steam: { appId, depots: { windows: null, macos: null, linux: null } } + })); + const config = readElectronConfig(root); + assert.equal(readSteamConfig(config, "steam:windows"), null); + assert.equal(createElectronPackagerOptions(root, config, "windows", path.join(root, "resources")).name, "test-game"); + } +}); + +test("SteamPipe maps package contents to install root and excludes development AppID", (t) => { + const root = fixture(t); + for (const [platform, arch, executable] of [ + ["windows", "x64", "test-game.exe"], ["linux", "x64", "test-game"], ["macos", "universal", "My Game.app"] + ]) { + const content = path.join(root, platform); + fs.mkdirSync(content); + if (platform === "macos") { + fs.mkdirSync(path.join(content, executable)); + } else { + fs.writeFileSync(path.join(content, executable), "binary", { mode: 0o755 }); + } + const scripts = `${content}-steampipe`; + // Match the builder's configured executableName; Windows cannot preserve POSIX execute bits. + writeSteamMetadata(content, `steam:${platform}`, arch, { appId: "2409460", depotId: "1234" }, "test-game"); + const launch = JSON.parse(fs.readFileSync(path.join(scripts, "launch.json"), "utf8")); + assert.equal(launch.executable, executable); + assert.equal(path.resolve(scripts, launch.contentRoot), content); + const depot = fs.readFileSync(path.join(scripts, "depot_build.vdf"), "utf8"); + assert.match(depot, /"Recursive" "1"/); + assert.match(depot, /"FileExclusion" "steam_appid.txt"/); + const app = fs.readFileSync(path.join(scripts, "app_build.vdf"), "utf8"); + assert.match(app, /"Preview" "0"/); + assert.doesNotMatch(app, /SetLive/); + assert.match(fs.readFileSync(path.join(scripts, "app_preview.vdf"), "utf8"), /"Preview" "1"/); + writeSteamMetadata(content, `steam:${platform}`, arch, { appId: "2409460", depotId: null }, "test-game"); + assert.equal(fs.existsSync(path.join(scripts, "app_build.vdf")), false); + } +}); + +test("Linux launch metadata uses the configured name even without POSIX execute permissions", (t) => { + const root = fixture(t); + const content = path.join(root, "linux"); + fs.mkdirSync(content); + // Reproduce permissions seen on Windows without requiring a Windows test runner. + fs.writeFileSync(path.join(content, "custom-game"), "binary", { mode: 0o644 }); + fs.writeFileSync(path.join(content, "resources.pak"), "resources"); + writeSteamMetadata(content, "steam:linux", "x64", { appId: "2409460", depotId: "1234" }, "custom-game"); + const launch = JSON.parse(fs.readFileSync(`${content}-steampipe/launch.json`, "utf8")); + assert.equal(launch.executable, "custom-game"); + assert.equal(path.resolve(`${content}-steampipe`, launch.contentRoot), content); + assert.throws(() => writeSteamMetadata(content, "steam:linux", "x64", null, "missing-game"), /Packaged Steam executable is missing/); +}); + +test("local protocol rejects foreign origins, encoded traversal and malformed paths", () => { + const root = path.resolve(os.tmpdir(), "game/resources"); + assert.equal(resolveAssetPath(root, "next2d://game/assets/test%20file.js"), path.join(root, "assets/test file.js")); + assert.equal(resolveAssetPath(root, "next2d://game/"), path.join(root, "index.html")); + for (const url of [ + "https://game/index.html", "next2d://other/index.html", "next2d://user@game/index.html", + "next2d://game/%2e%2e%2fsecret", "next2d://game/%5c..%5csecret", "next2d://game/%00", "next2d://game/%ZZ" + ]) { + assert.equal(resolveAssetPath(root, url), null, url); + } +}); + +test("release mode requires signing and notarization credentials", (t) => { + const root = fixture(t); + const previous = { ...process.env }; + t.after(() => { process.env = previous; }); + process.env.NEXT2D_STEAM_RELEASE = "1"; + delete process.env.APPLE_SIGNING_IDENTITY; + delete process.env.APPLE_NOTARY_PROFILE; + const config = readElectronConfig(root); + assert.throws(() => createElectronPackagerOptions(root, config, "macos", path.join(root, "resources")), /APPLE_SIGNING_IDENTITY/); + process.env.APPLE_SIGNING_IDENTITY = "test identity"; + assert.throws(() => createElectronPackagerOptions(root, config, "macos", path.join(root, "resources")), /APPLE_NOTARY_PROFILE/); + process.env.APPLE_NOTARY_PROFILE = "test profile"; + const options = createElectronPackagerOptions(root, config, "macos", path.join(root, "resources")); + assert.ok(options.osxSign); + assert.equal(options.osxSign.continueOnError, false); + assert.deepEqual(options.osxNotarize, { keychainProfile: "test profile" }); +}); + +test("configured macOS signing must fail the build with or without notarization", (t) => { + const root = fixture(t); + const previous = { ...process.env }; + t.after(() => { process.env = previous; }); + delete process.env.NEXT2D_STEAM_RELEASE; + process.env.APPLE_SIGNING_IDENTITY = "test identity"; + process.env.APPLE_NOTARY_PROFILE = "test profile"; + for (const notarize of [false, true]) { + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ macos: { sign: true, notarize } })); + const config = readElectronConfig(root); + const options = createElectronPackagerOptions(root, config, "macos", path.join(root, "resources")); + assert.equal(options.osxSign?.continueOnError, false); + assert.equal(Boolean(options.osxNotarize), notarize); + // Signing settings must not affect other target operating systems. + for (const os of ["windows", "linux"] as const) { + const other = createElectronPackagerOptions(root, config, os, path.join(root, "resources")); + assert.equal(other.osxSign, undefined); + assert.equal(other.osxNotarize, undefined); + } + } +}); diff --git a/tests/native.test.ts b/tests/native.test.ts new file mode 100644 index 0000000..a5645c5 --- /dev/null +++ b/tests/native.test.ts @@ -0,0 +1,104 @@ +import { before, test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { spawnSync } from "node:child_process"; +import { getCapacitorCommand } from "../dist/native.js"; + +// Allow a cold npm cache to download SDKs before the short per-command timeouts. +before(async () => { await getCapacitorCommand(); }, { timeout: 180000 }); + +const fixture = (t, platform) => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d native ")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "test-game", version: "1.0.0" })); + fs.writeFileSync(path.join(root, "capacitor.config.json"), JSON.stringify({ + appId: "app.example.game", appName: "Test Game", webDir: "obsolete", + [platform]: { path: `native/${platform}` } + })); + const web = path.join(root, "custom output", platform, "prd"); + fs.mkdirSync(web, { recursive: true }); + fs.writeFileSync(path.join(web, "index.html"), "Game content"); + return root; +}; + +const run = (root, platform, action = "syncNative") => spawnSync(process.execPath, ["--input-type=module", "-e", ` + import { ctx } from ${JSON.stringify(new URL("../dist/context.js", import.meta.url).href)}; + import { ${action} } from ${JSON.stringify(new URL("../dist/native.js", import.meta.url).href)}; + Object.assign(ctx, { platform: ${JSON.stringify(platform)}, platformDir: ${JSON.stringify(platform)}, environment: "prd", outDir: "custom output" }); + await ${action}(); +`], { + cwd: root, encoding: "utf8", timeout: 30000, + // Test add/sync only. Capacitor's optional Gradle discovery must not start a native build. + env: { ...process.env, JAVA_HOME: path.join(root, "no-jdk") } +}); + +const succeeded = (result) => assert.equal(result.status, 0, result.stdout + result.stderr); + +test("Android add/sync uses builder SDKs with no game Capacitor installation and keeps plugins/hooks", (t) => { + const root = fixture(t, "android"); + const plugin = path.join(root, "node_modules/test-plugin"); + fs.mkdirSync(path.join(plugin, "android/src/main"), { recursive: true }); + fs.writeFileSync(path.join(plugin, "package.json"), JSON.stringify({ + name: "test-plugin", version: "1.0.0", capacitor: { android: { src: "android" } } + })); + fs.writeFileSync(path.join(plugin, "android/build.gradle"), "// Test plugin"); + const packageFile = path.join(root, "package.json"); + const pkg = JSON.parse(fs.readFileSync(packageFile, "utf8")); + pkg.dependencies = { "test-plugin": "1.0.0" }; + pkg.scripts = { "capacitor:sync:before": "node hook.cjs" }; + fs.writeFileSync(packageFile, JSON.stringify(pkg)); + fs.writeFileSync(path.join(root, "hook.cjs"), 'require("node:fs").writeFileSync("hook-cwd.txt", process.cwd());'); + const originalPackage = fs.readFileSync(packageFile, "utf8"); + succeeded(run(root, "android")); + assert.equal(fs.realpathSync(fs.readFileSync(path.join(root, "hook-cwd.txt"), "utf8")), fs.realpathSync(root)); + const native = path.join(root, "native/android"); + const settings = fs.readFileSync(path.join(native, "capacitor.settings.gradle"), "utf8"); + assert.match(settings, /include ':capacitor-android'/); + assert.match(settings, /include ':test-plugin'/); + const sdkPath = settings.match(/project\(':capacitor-android'\)\.projectDir = new File\('([^']+)'\)/)[1]; + assert.ok(fs.existsSync(path.resolve(native, sdkPath, "build.gradle"))); + assert.match(fs.readFileSync(path.join(native, "app/src/main/assets/public/index.html"), "utf8"), /Game content/); + assert.equal(JSON.parse(fs.readFileSync(path.join(root, "capacitor.config.json"))).webDir, "custom output/android/prd/"); + fs.writeFileSync(path.join(native, "custom-native.txt"), "keep"); + succeeded(run(root, "android")); + assert.equal(fs.readFileSync(path.join(native, "custom-native.txt"), "utf8"), "keep"); + assert.equal(fs.readFileSync(packageFile, "utf8"), originalPackage); + assert.equal(fs.existsSync(path.join(root, "node_modules/@capacitor")), false); +}); + +test("iOS SPM add/sync uses builder SDKs without touching game dependencies", { skip: process.platform !== "darwin" }, (t) => { + const root = fixture(t, "ios"); + succeeded(run(root, "ios")); + const native = path.join(root, "native/ios/App"); + assert.match(fs.readFileSync(path.join(native, "CapApp-SPM/Package.swift"), "utf8"), /capacitor-swift-pm/); + assert.match(fs.readFileSync(path.join(native, "App/public/index.html"), "utf8"), /Game content/); + fs.writeFileSync(path.join(native, "custom-native.txt"), "keep"); + succeeded(run(root, "ios")); + assert.equal(fs.readFileSync(path.join(native, "custom-native.txt"), "utf8"), "keep"); + assert.equal(fs.existsSync(path.join(root, "node_modules")), false); +}); + +test("native CLI failures stop build/open and return a nonzero exit", (t) => { + const root = fixture(t, "android"); + fs.rmSync(path.join(root, "custom output"), { recursive: true }); + for (const action of ["buildNative", "openNative", "runNative"]) { + const result = run(root, "android", action); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /Capacitor (?:sync|run|add) android failed/); + } +}); + +test("builder CLI resolution is independent of the game and supplies NODE_PATH", async (t) => { + const root = fixture(t, "android"); + const { cli, env } = await getCapacitorCommand(); + assert.ok(fs.existsSync(cli)); + const result = spawnSync(process.execPath, ["-e", ` + for (const name of ['core', 'ios', 'android']) { + console.log(require.resolve('@capacitor/' + name + '/package.json', { paths: [process.cwd()] })); + } + `], { cwd: root, env, encoding: "utf8" }); + succeeded(result); + assert.equal(result.stdout.trim().split("\n").length, 3); +}); diff --git a/tests/project-vite.test.ts b/tests/project-vite.test.ts new file mode 100644 index 0000000..d0ec169 --- /dev/null +++ b/tests/project-vite.test.ts @@ -0,0 +1,56 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import path from "node:path"; +import os from "node:os"; +import { loadProjectVite } from "../dist/project-vite.js"; +import { minifyJs } from "../dist/xbox.js"; + +const fixture = (t, type = "module", source = "export const loadConfigFromFile = () => ({ config: { build: { outDir: 'game-output' } } });") => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d-project-vite-")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + const vite = path.join(root, "node_modules/vite"); + fs.mkdirSync(vite, { recursive: true }); + fs.writeFileSync(path.join(root, "package.json"), "{}"); + fs.writeFileSync(path.join(vite, "package.json"), JSON.stringify({ name: "vite", type, exports: "./index.js" })); + fs.writeFileSync(path.join(vite, "index.js"), source); + return root; +}; + +test("resolves the game's Vite instead of the builder's development dependency", async (t) => { + const vite = await loadProjectVite(fixture(t)); + const result = await vite.loadConfigFromFile({ command: "build", mode: "build" }); + assert.equal(result.config.build.outDir, "game-output"); +}); + +test("accepts the CJS API wrapper used by older Vite versions", async (t) => { + const vite = await loadProjectVite(fixture(t, "commonjs", "module.exports = { loadConfigFromFile: () => 'cjs' };")); + assert.equal(await vite.loadConfigFromFile({ command: "build", mode: "build" }), "cjs"); +}); + +test("missing or broken project Vite reports a useful error instead of using builder's copy", async (t) => { + const root = fixture(t); + fs.rmSync(path.join(root, "node_modules"), { recursive: true, force: true }); + await assert.rejects(loadProjectVite(root), /Vite is not installed/); + const broken = fixture(t, "module", "export const wrong = true;"); + await assert.rejects(loadProjectVite(broken), /does not expose loadConfigFromFile/); +}); + +test("Xbox uses the older Vite transform API when minifySync is unavailable", async (t) => { + const original = process.cwd(); + const root = fixture(t, "commonjs", `module.exports = { + loadConfigFromFile() {}, + transformWithEsbuild(code, name, options) { + if (name !== "bootstrap.js" || !options.minify || options.legalComments !== "none") { + throw new Error("Wrong minifier options"); + } + return Promise.resolve({ code: "globalThis.result=3;" }); + } + };`); + process.chdir(root); + try { + assert.equal(await minifyJs("bootstrap.js", "globalThis.result = 1 + 2;"), "globalThis.result=3;"); + } finally { + process.chdir(original); + } +}); diff --git a/tests/steam-shared.test.ts b/tests/steam-shared.test.ts new file mode 100644 index 0000000..fe4fa1d --- /dev/null +++ b/tests/steam-shared.test.ts @@ -0,0 +1,149 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { readElectronConfig } from "../dist/electron-config.js"; +import { readSteamConfig, recordSteamPackage, writeSharedSteamDepots } from "../dist/steam.js"; +import { parseArgv } from "../dist/cli.js"; + +const fixture = (t, depots = { windows: 2409461, macos: "2409461", linux: 2409461 }) => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d shared depot ")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "test-game", version: "1.0.0" })); + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ + appName: "My Game", executableName: "my-game", steam: { appId: 2409460, depots } + })); + return { root, steamRoot: path.join(root, "custom output/steam"), config: readElectronConfig(root) }; +}; + +const addPackage = (f, os, arch = os === "macos" ? "universal" : "x64", version = "1.0.0") => { + const native = { windows: "win32", macos: "darwin", linux: "linux" }[os]; + const content = path.join(f.steamRoot, os, "build/prd", `My Game-${native}-${arch}`); + fs.mkdirSync(content, { recursive: true }); + const exe = os === "macos" ? "My Game.app" : os === "windows" ? "my-game.exe" : "my-game"; + if (os === "macos") fs.mkdirSync(path.join(content, exe)); + else fs.writeFileSync(path.join(content, exe), "binary", { mode: 0o755 }); + fs.writeFileSync(path.join(content, "resources.pak"), os); + recordSteamPackage(content, `steam:${os}`, arch, f.config, version); + return content; +}; + +const scriptDir = (f) => path.join(f.steamRoot, "shared/prd/depot-2409461"); + +test("one OS with a shared Depot ID exports metadata but no partial upload VDF", (t) => { + const f = fixture(t); + assert.deepEqual(readSteamConfig(f.config, "steam:macos").sharedPlatforms, ["windows", "macos", "linux"]); + const content = addPackage(f, "macos"); + assert.equal(fs.existsSync(`${content}-steampipe/app_build.vdf`), false); + const launch = JSON.parse(fs.readFileSync(`${content}-steampipe/launch.json`, "utf8")); + assert.equal(launch.executable, "macos/My Game.app"); + assert.equal(launch.localExecutable, "My Game.app"); + const pending = writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + assert.equal(pending.length, 1); + assert.equal(fs.existsSync(path.join(scriptDir(f), "app_build.vdf")), false); + const status = JSON.parse(fs.readFileSync(path.join(scriptDir(f), "launch.json"), "utf8")); + assert.equal(status.ready, false); + assert.equal(status.missing.length, 2); +}); + +test("shared manifest maps every OS into separate directories and uses latest architecture", (t) => { + const f = fixture(t); + for (const os of ["windows", "macos", "linux"]) addPackage(f, os); + const latest = addPackage(f, "macos", "arm64"); + assert.deepEqual(writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"), []); + const dir = scriptDir(f); + const depot = fs.readFileSync(path.join(dir, "depot_build.vdf"), "utf8"); + assert.equal((depot.match(/"FileMapping"/g) || []).length, 3); + for (const os of ["windows", "macos", "linux"]) { + assert.ok(depot.includes(`"DepotPath" "${os}/"`)); + assert.ok(depot.includes(`"LocalPath" "${os}/build/prd/My Game-`)); + } + assert.ok(depot.includes(path.relative(f.steamRoot, latest).replaceAll("\\", "/") + "/*")); + assert.doesNotMatch(depot, /darwin-universal/); + assert.doesNotMatch(depot, /steampipe|steam-package\.json/); + const app = fs.readFileSync(path.join(dir, "app_build.vdf"), "utf8"); + assert.match(app, /"ContentRoot" "\.\.\/\.\.\/\.\."/); + assert.equal((app.match(/"2409461" "depot_build.vdf"/g) || []).length, 1); + assert.doesNotMatch(app, /SetLive/); + assert.match(fs.readFileSync(path.join(dir, "app_preview.vdf"), "utf8"), /"Preview" "1"/); + const status = JSON.parse(fs.readFileSync(path.join(dir, "launch.json"), "utf8")); + assert.equal(status.ready, true); + assert.deepEqual(status.launches.map(x => x.executable), ["windows/my-game.exe", "macos/My Game.app", "linux/my-game"]); +}); + +test("missing or outdated packages invalidate previously ready manifests", (t) => { + const f = fixture(t); + for (const os of ["windows", "macos", "linux"]) addPackage(f, os); + writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + assert.ok(fs.existsSync(path.join(scriptDir(f), "app_build.vdf"))); + assert.equal(writeSharedSteamDepots(f.steamRoot, "prd", f.config, "2.0.0").length, 1); + assert.equal(fs.existsSync(path.join(scriptDir(f), "app_build.vdf")), false); + writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + fs.rmSync(path.join(f.steamRoot, "windows/build/prd/steam-package.json")); + assert.equal(writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0").length, 1); + assert.equal(fs.existsSync(path.join(scriptDir(f), "depot_build.vdf")), false); +}); + +test("mixed shared and separate depots remain independent; changing config removes obsolete VDFs", (t) => { + const f = fixture(t, { windows: 2409461, macos: 2409461, linux: 2409462 }); + const windows = addPackage(f, "windows"); + addPackage(f, "macos"); + const linux = addPackage(f, "linux"); + fs.writeFileSync(`${windows}-steampipe/app_build.vdf`, "obsolete standalone upload"); + writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + assert.equal(fs.existsSync(`${windows}-steampipe/app_build.vdf`), false); + assert.ok(fs.existsSync(`${linux}-steampipe/app_build.vdf`)); + const depot = fs.readFileSync(path.join(scriptDir(f), "depot_build.vdf"), "utf8"); + assert.doesNotMatch(depot, /linux/); + f.config.steam.depots.macos = "2409463"; + writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + assert.equal(fs.existsSync(path.join(scriptDir(f), "app_build.vdf")), false); +}); + +test("manifest CLI requires a Steam target and cannot rebuild or preview", () => { + const args = ["--platform", "steam:macos", "--env", "prd", "--steam-manifest"]; + assert.equal(parseArgv(args).steamManifest, true); + assert.equal(parseArgv(args).hasHelp, false); + for (const flag of ["--preview", "--build", "--open"]) assert.equal(parseArgv([...args, flag]).hasHelp, true); + assert.equal(parseArgv([...args, "--arch", "arm64"]).hasHelp, true); + assert.equal(parseArgv(["--platform", "web", "--env", "prd", "--steam-manifest"]).hasHelp, true); +}); + +test("legacy standalone VDFs are removed even without a package pointer", (t) => { + const f = fixture(t); + const scripts = path.join(f.steamRoot, "windows/build/prd/My Game-win32-x64-steampipe"); + fs.mkdirSync(scripts, { recursive: true }); + fs.writeFileSync(path.join(scripts, "app_build.vdf"), "old upload"); + writeSharedSteamDepots(f.steamRoot, "prd", f.config, "1.0.0"); + assert.equal(fs.existsSync(path.join(scripts, "app_build.vdf")), false); +}); + +test("manifest CLI assembles relocated CI packages without a web build, and fails on incomplete input", async (t) => { + const { spawnSync } = await import("node:child_process"); + const { fileURLToPath } = await import("node:url"); + const f = fixture(t); + for (const os of ["windows", "macos", "linux"]) addPackage(f, os); + const destination = path.join(f.root, "collected/steam"); + fs.mkdirSync(path.dirname(destination)); + fs.renameSync(f.steamRoot, destination); + const vite = path.join(f.root, "node_modules/vite"); + fs.mkdirSync(vite, { recursive: true }); + fs.writeFileSync(path.join(vite, "package.json"), JSON.stringify({ name: "vite", type: "module", main: "index.js" })); + fs.writeFileSync(path.join(vite, "index.js"), 'export const loadConfigFromFile = async () => ({ config: { build: { outDir: "collected" } } });'); + const run = () => spawnSync(process.execPath, [fileURLToPath(new URL("../dist/index.js", import.meta.url)), + "--platform", "steam:macos", "--env", "prd", "--steam-manifest"], { + cwd: f.root, encoding: "utf8", timeout: 10000, env: { ...process.env, npm_config_offline: "true" } + }); + let result = run(); + assert.equal(result.status, 0, result.stderr); + assert.doesNotMatch(result.stdout, /Packaging Electron|vite .*building/); + const script = path.join(destination, "shared/prd/depot-2409461/app_build.vdf"); + assert.ok(fs.existsSync(script)); + assert.doesNotMatch(fs.readFileSync(script, "utf8"), /custom output/); + fs.rmSync(path.join(destination, "linux/build/prd/steam-package.json")); + result = run(); + assert.equal(result.status, 1); + assert.match(result.stderr, /Shared Steam depots are incomplete/); + assert.equal(fs.existsSync(script), false); +}); diff --git a/tests/steam-upload.test.ts b/tests/steam-upload.test.ts new file mode 100644 index 0000000..a4e4209 --- /dev/null +++ b/tests/steam-upload.test.ts @@ -0,0 +1,205 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { spawnSync } from "node:child_process"; +import { fileURLToPath } from "node:url"; +import { readElectronConfig } from "../dist/electron-config.js"; +import { recordSteamPackage } from "../dist/steam.js"; +import { prepareSteamUpload, validateSteamBranch } from "../dist/steam-upload.js"; +import { parseArgv } from "../dist/cli.js"; + +const fixture = (t, depots = { windows: 2409461, macos: 2409461, linux: 2409461 }) => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d upload ")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + fs.writeFileSync(path.join(root, "package.json"), JSON.stringify({ name: "test-game", version: "1.0.0" })); + fs.writeFileSync(path.join(root, "electron.config.json"), JSON.stringify({ + appName: "Test Game", executableName: "my-game", steam: { appId: 2409460, branch: "internal", depots } + })); + const config = readElectronConfig(root); + const steamRoot = path.join(root, "custom output/steam"); + const contents = {}; + for (const platform of Object.keys(depots)) { + if (!depots[platform]) continue; + const content = path.join(steamRoot, platform, "build/prd", `Test Game-${platform}`); + fs.mkdirSync(content, { recursive: true }); + if (platform === "macos") fs.mkdirSync(path.join(content, "Test Game.app")); + else fs.writeFileSync(path.join(content, platform === "windows" ? "my-game.exe" : "my-game"), "binary", { mode: 0o755 }); + recordSteamPackage(content, `steam:${platform}`, "x64", config, "1.0.0"); + contents[platform] = content; + } + return { root, steamRoot, environment: "prd", contents }; +}; + +const cli = (f, args = [], env = {}) => spawnSync(process.execPath, [ + fileURLToPath(new URL("../dist/index.js", import.meta.url)), + "--steam-upload", "--env", "prd", "--steam-root", f.steamRoot, ...args +], { + cwd: f.root, encoding: "utf8", timeout: 10000, + env: { ...process.env, STEAM_USERNAME: "", STEAMCMD: path.join(f.root, "missing-steamcmd"), ...env } +}); + +test("Steam upload CLI is platform independent and rejects mixed actions, missing values and unknown flags", () => { + const args = ["--steam-upload", "--env", "prd"]; + assert.equal(parseArgv(args).hasHelp, false); + assert.equal(parseArgv([...args, "--dry-run"]).dryRun, true); + assert.equal(parseArgv([...args, "--steam-branch", "internal"]).steamBranch, "internal"); + assert.equal(parseArgv([...args, "--steam-comment", "内部テスト用"]).steamComment, "内部テスト用"); + for (const extra of [["--platform", "steam:macos"], ["--steam-manifest"], ["--preview"], ["--build"], ["--open"], + ["--arch", "x64"], ["--steam-branch"], ["--steam-root"], ["--steam-comment"], + ["--steam-comment", ""], ["--steam-comment", "--dry-run"], ["--dryrun"]]) { + assert.equal(parseArgv([...args, ...extra]).hasHelp, true, extra.join(" ")); + } + assert.equal(parseArgv(["--steam-upload"]).hasHelp, true); + assert.equal(parseArgv(["--platform", "web", "--env", "prd", "--dry-run"]).hasHelp, true); + assert.equal(parseArgv(["--platform", "web", "--env", "prd", "--steam-comment", "test"]).hasHelp, true); +}); + +test("upload combines a shared depot once, sets internal, and preserves ordinary build manifests", (t) => { + const f = fixture(t); + const plan = prepareSteamUpload(f); + const manifest = fs.readFileSync(plan.manifest, "utf8"); + assert.match(manifest, /"Desc" "Test Game 1\.0\.0 \(prd, internal\)"/); + assert.equal(plan.comment, "Test Game 1.0.0 (prd, internal)"); + assert.match(manifest, /"SetLive" "internal"/); + assert.match(manifest, /"Preview" "0"/); + assert.equal((manifest.match(/"2409461" "depot_2409461.vdf"/g) || []).length, 1); + assert.equal(plan.launches.length, 3); + const depot = fs.readFileSync(path.join(path.dirname(plan.manifest), "depot_2409461.vdf"), "utf8"); + for (const os of ["windows", "macos", "linux"]) assert.match(depot, new RegExp(`"DepotPath" "${os}/"`)); + assert.doesNotMatch(depot, /steam-package\.json|uploads\//); + assert.match(depot, /"FileExclusion" "steam_appid.txt"/); + const preview = prepareSteamUpload({ ...f, dryRun: true }); + assert.notEqual(preview.manifest, plan.manifest); + assert.doesNotMatch(fs.readFileSync(preview.manifest, "utf8"), /SetLive/); + assert.match(fs.readFileSync(preview.manifest, "utf8"), /"Preview" "1"/); + assert.equal(fs.readFileSync(plan.manifest, "utf8"), manifest); +}); + +test("separate and shared depots are uploaded in the same app build with correct install paths", (t) => { + const f = fixture(t, { windows: 2409461, macos: 2409461, linux: 2409462 }); + const plan = prepareSteamUpload({ ...f, branch: "qa" }); + const manifest = fs.readFileSync(plan.manifest, "utf8"); + for (const depot of [2409461, 2409462]) assert.ok(manifest.includes(`"${depot}" "depot_${depot}.vdf"`)); + assert.match(manifest, /"SetLive" "qa"/); + const linux = fs.readFileSync(path.join(path.dirname(plan.manifest), "depot_2409462.vdf"), "utf8"); + assert.match(linux, /"DepotPath" "\."/); + assert.equal(plan.launches.find(x => x.platform === "steam:linux").executable, "my-game"); + assert.doesNotMatch(fs.readFileSync(`${f.contents.linux}-steampipe/app_build.vdf`, "utf8"), /SetLive/); +}); + +test("missing OS, stale version/IDs, invalid arch and escaped package paths block upload before SteamCMD", (t) => { + const f = fixture(t); + const file = path.join(path.dirname(f.contents.windows), "steam-package.json"); + const original = JSON.parse(fs.readFileSync(file, "utf8")); + for (const patch of [{ version: "0.9.0" }, { appId: "480" }, { depotId: "2409462" }, { arch: "ia32" }, + { contentRoot: "../secret" }, { contentRoot: "..\\secret" }]) { + fs.writeFileSync(file, JSON.stringify({ ...original, ...patch })); + const result = cli(f, [], { STEAM_USERNAME: "test_builder" }); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /windows package is missing or outdated/); + assert.doesNotMatch(result.stderr, /Cannot start SteamCMD/); + } + fs.rmSync(file); + assert.throws(() => prepareSteamUpload(f), /windows package is missing or outdated/); + assert.equal(fs.existsSync(path.join(f.steamRoot, "uploads")), false); +}); + +test("unsafe/default branches, invalid env and absent IDs are rejected", (t) => { + for (const branch of ["default", "Default", "public", "none", "", "test beta", "x\"\nSetLive", "../internal", null]) { + assert.throws(() => validateSteamBranch(branch)); + } + const f = fixture(t, {}); + assert.throws(() => prepareSteamUpload(f), /at least one Steam Depot/); + assert.throws(() => prepareSteamUpload({ ...f, environment: "../prd" }), /--env/); + const config = JSON.parse(fs.readFileSync(path.join(f.root, "electron.config.json"), "utf8")); + config.steam.appId = null; + fs.writeFileSync(path.join(f.root, "electron.config.json"), JSON.stringify(config)); + assert.throws(() => prepareSteamUpload(f), /steam.appId/); +}); + +test("dry-run CLI needs no SteamCMD, credentials, Vite or tool downloads", (t) => { + const f = fixture(t); + const result = cli(f, ["--dry-run"], { npm_config_cache: path.join(f.root, "empty-cache"), npm_config_offline: "true" }); + assert.equal(result.status, 0, result.stdout + result.stderr); + assert.match(result.stdout, /SteamCMD was not started/); + assert.match(result.stdout, /beta branch internal/); + assert.equal(fs.existsSync(path.join(f.root, "empty-cache")), false); + assert.equal(fs.existsSync(path.join(f.root, "node_modules")), false); +}); + +test("dry-run CLI preserves a custom build comment in its manifest, plan and output", (t) => { + const f = fixture(t); + const comment = "内部テスト:プレイヤー's 入力を修正 (revision abc123)"; + const result = cli(f, ["--dry-run", "--steam-comment", comment]); + assert.equal(result.status, 0, result.stdout + result.stderr); + assert.ok(result.stdout.includes(`Comment: ${comment}`)); + const manifest = result.stdout.match(/^Manifest: (.+)$/m)[1].trim(); + assert.ok(fs.readFileSync(manifest, "utf8").includes(`"Desc" "${comment}"`)); + const plan = JSON.parse(fs.readFileSync(path.join(path.dirname(manifest), "upload-plan.json"), "utf8")); + assert.equal(plan.comment, comment); +}); + +test("invalid comments fail before writing manifests or starting SteamCMD", (t) => { + const f = fixture(t); + for (const comment of ["", " ", "bad\"comment", "bad\\comment", "bad\ncomment", "bad\rcomment", "bad\tcomment", "bad\0comment", null]) { + assert.throws(() => prepareSteamUpload({ ...f, comment }), /--steam-comment/); + } + const result = cli(f, ["--steam-comment", " "], { STEAM_USERNAME: "test_builder" }); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /--steam-comment/); + assert.doesNotMatch(result.stderr, /Cannot start SteamCMD/); + assert.equal(fs.existsSync(path.join(f.steamRoot, "uploads")), false); +}); + +test("upload requires a cached-login account and propagates missing executable errors", (t) => { + const f = fixture(t); + assert.match(cli(f).stderr, /Set STEAM_USERNAME/); + assert.match(cli(f, [], { STEAM_USERNAME: "user +quit" }).stderr, /Set STEAM_USERNAME/); + assert.match(cli(f, [], { STEAM_USERNAME: "test_builder" }).stderr, /Cannot start SteamCMD/); +}); + +test("SteamCMD receives literal paths, runs once, saves BuildID, and propagates exit/output failures", { skip: process.platform === "win32" }, (t) => { + const f = fixture(t); + const command = path.join(f.root, "fake steamcmd"); + const calls = path.join(f.root, "calls.json"); + fs.writeFileSync(command, `#!/usr/bin/env node +const fs = require('node:fs'); +fs.writeFileSync(process.env.TEST_CALLS, JSON.stringify(process.argv.slice(2))); +console.log(process.env.TEST_OUTPUT); +process.exit(Number(process.env.TEST_CODE || 0)); +`, { mode: 0o755 }); + const env = { STEAM_USERNAME: "test_builder", STEAMCMD: command, TEST_CALLS: calls, + TEST_OUTPUT: "Success! App '2409460' fully built (BuildID 123456)." }; + const result = cli(f, [], env); + assert.equal(result.status, 0, result.stdout + result.stderr); + const args = JSON.parse(fs.readFileSync(calls, "utf8")); + assert.deepEqual(args.slice(0, 7), ["+@ShutdownOnFailedCommand", "1", "+@NoPromptForPassword", "1", "+login", "test_builder", "+run_app_build"]); + assert.equal(args.length, 9); + assert.equal(args[8], "+quit"); + assert.ok(fs.existsSync(args[7])); + assert.equal(JSON.parse(fs.readFileSync(path.join(path.dirname(args[7]), "upload-result.json"), "utf8")).buildId, "123456"); + // Actual SteamCMD output includes a timestamp and uses a different completion message. + const currentOutput = "[2026-09-24 08:02:22]: Successfully finished AppID 2409460 build (BuildID 25493101).\r\nUnloading Steam API...OK"; + const comment = "内部テスト用ビルド"; + const current = cli(f, ["--steam-comment", comment], { ...env, TEST_OUTPUT: currentOutput }); + assert.equal(current.status, 0, current.stdout + current.stderr); + const currentArgs = JSON.parse(fs.readFileSync(calls, "utf8")); + assert.ok(fs.readFileSync(currentArgs[7], "utf8").includes(`"Desc" "${comment}"`)); + const currentRecord = JSON.parse(fs.readFileSync(path.join(path.dirname(currentArgs[7]), "upload-result.json"), "utf8")); + assert.equal(currentRecord.buildId, "25493101"); + assert.equal(currentRecord.requestedBranch, "internal"); + for (const failure of [{ TEST_CODE: "7" }, { TEST_OUTPUT: "ERROR! Failed to build App." }, + { TEST_OUTPUT: "Logged in but no build happened" }, { TEST_OUTPUT: env.TEST_OUTPUT + "\nFailed to set build live" }, + { TEST_OUTPUT: currentOutput, TEST_CODE: "7" }, + { TEST_OUTPUT: currentOutput.replace("AppID 2409460", "AppID 480") }, + { TEST_OUTPUT: currentOutput.replace("BuildID 25493101", "BuildID unknown") }, + { TEST_OUTPUT: currentOutput + "\nERROR! Failed to set build live" }, + { TEST_OUTPUT: "ERROR! Failed to build depot.\n" + currentOutput }]) { + const failed = cli(f, [], { ...env, ...failure }); + assert.notEqual(failed.status, 0, failed.stdout + failed.stderr); + const failedArgs = JSON.parse(fs.readFileSync(calls, "utf8")); + assert.equal(fs.existsSync(path.join(path.dirname(failedArgs[7]), "upload-result.json")), false); + } +}); diff --git a/tests/tool-packages.test.ts b/tests/tool-packages.test.ts new file mode 100644 index 0000000..a72fe46 --- /dev/null +++ b/tests/tool-packages.test.ts @@ -0,0 +1,70 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import fs from "node:fs"; +import os from "node:os"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; +import { spawnSync } from "node:child_process"; + +const fixture = (t) => { + const root = fs.mkdtempSync(path.join(os.tmpdir(), "next2d tool paths ")); + t.after(() => fs.rmSync(root, { recursive: true, force: true })); + return root; +}; + +const installation = (root, directory, packages) => { + const modules = path.join(root, directory, "node_modules"); + fs.mkdirSync(path.join(modules, ".bin"), { recursive: true }); + for (const [name, version] of Object.entries(packages)) { + fs.mkdirSync(path.join(modules, name), { recursive: true }); + fs.writeFileSync(path.join(modules, name, "package.json"), JSON.stringify({ name, version })); + } + return path.join(modules, ".bin"); +}; + +const resolve = (root, bins, packages) => spawnSync(process.execPath, [ + fileURLToPath(new URL("../dist/resolve-tool-packages.js", import.meta.url)) +], { + encoding: "utf8", + env: { + ...process.env, PATH: bins.join(path.delimiter), + NEXT2D_TOOL_PACKAGES: JSON.stringify(packages), NEXT2D_TOOL_RESULT: path.join(root, "result.json") + } +}); + +test("tool resolution skips unrelated project versions and returns the pinned npx installation", (t) => { + const root = fixture(t); + const old = installation(root, "game", { "@electron/packager": "18.4.4" }); + const pinned = installation(root, "npm cache", { "@electron/packager": "20.3.0" }); + const result = resolve(root, [old, pinned], { "@electron/packager": "20.3.0" }); + assert.equal(result.status, 0, result.stderr); + const paths = JSON.parse(fs.readFileSync(path.join(root, "result.json"), "utf8")); + assert.equal(paths["@electron/packager"], path.join(path.dirname(pinned), "@electron/packager/package.json")); +}); + +test("tool resolution rejects incomplete or mismatched SDK installations", (t) => { + const root = fixture(t); + const cli = installation(root, "first", { "@capacitor/cli": "8.5.2" }); + const sdk = installation(root, "second", { "@capacitor/core": "8.5.2" }); + const mismatched = installation(root, "third", { "@capacitor/cli": "8.5.2", "@capacitor/core": "8.0.0" }); + const result = resolve(root, [cli, sdk, mismatched], { "@capacitor/cli": "8.5.2", "@capacitor/core": "8.5.2" }); + assert.notEqual(result.status, 0); + assert.match(result.stderr, /Could not resolve the requested build tools/); + assert.equal(fs.existsSync(path.join(root, "result.json")), false); +}); + +test("loading platform modules works offline with an empty npm cache without acquiring tools", (t) => { + const root = fixture(t); + const cache = path.join(root, "empty-cache"); + const result = spawnSync(process.execPath, [ + "--input-type=module", "-e", + `await import(${JSON.stringify(new URL("../dist/electron.js", import.meta.url).href)}); + await import(${JSON.stringify(new URL("../dist/native.js", import.meta.url).href)});` + ], { + cwd: root, encoding: "utf8", timeout: 10000, + env: { ...process.env, npm_config_cache: cache, npm_config_offline: "true" } + }); + assert.equal(result.status, 0, result.stdout + result.stderr); + assert.doesNotMatch(result.stdout, /Preparing .* tools via npx/); + assert.equal(fs.existsSync(cache), false); +}); diff --git a/tests/xbox.test.ts b/tests/xbox.test.ts index 7b9db1d..8a22428 100644 --- a/tests/xbox.test.ts +++ b/tests/xbox.test.ts @@ -82,7 +82,7 @@ test("walkFiles: 存在しないディレクトリは空配列", () => { assert.deepEqual(walkFiles(path.join(os.tmpdir(), "n2d-does-not-exist-xyz")), []); }); -test("minifyJs: 圧縮しコメント除去、グローバル名は保持", () => { +test("minifyJs: 圧縮しコメント除去、グローバル名は保持", async () => { const src = ` // このコメントは除去される globalThis.__next2d_boot = function () { @@ -90,14 +90,14 @@ globalThis.__next2d_boot = function () { return longLocalVariableName; }; `; - const out = minifyJs("js/bootstrap.js", src); + const out = await minifyJs("js/bootstrap.js", src); assert.ok(out.length < src.length, "縮む"); assert.ok(!out.includes("除去される"), "コメント除去"); assert.ok(out.includes("__next2d_boot"), "グローバル名は保持 (ゲームが参照)"); assert.ok(!/\blongLocalVariableName\b/.test(out), "ローカル名はマングル"); }); -test("minifyJs: 不正な JS は元コードのまま返す (埋め込み継続)", () => { +test("minifyJs: 不正な JS は元コードのまま返す (埋め込み継続)", async () => { const broken = "globalThis.x = (((;"; - assert.equal(minifyJs("js/bootstrap.js", broken), broken); + assert.equal(await minifyJs("js/bootstrap.js", broken), broken); });