diff --git a/.angular-cli.json b/.angular-cli.json deleted file mode 100644 index 78ce526..0000000 --- a/.angular-cli.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "$schema": "./node_modules/@angular/cli/lib/config/schema.json", - "project": { - "name": "sms-back-reader-2" - }, - "apps": [ - { - "root": "src", - "outDir": "dist", - "assets": [ - "assets", - "favicon.ico" - ], - "index": "index.html", - "main": "main.ts", - "polyfills": "polyfills.ts", - "test": "test.ts", - "tsconfig": "tsconfig.app.json", - "testTsconfig": "tsconfig.spec.json", - "prefix": "app", - "styles": [ - "styles.css" - ], - "scripts": [], - "environmentSource": "environments/environment.ts", - "environments": { - "dev": "environments/environment.ts", - "prod": "environments/environment.prod.ts" - } - } - ], - "e2e": { - "protractor": { - "config": "./protractor.conf.js" - } - }, - "lint": [ - { - "project": "src/tsconfig.app.json", - "exclude": "**/node_modules/**" - }, - { - "project": "src/tsconfig.spec.json", - "exclude": "**/node_modules/**" - }, - { - "project": "e2e/tsconfig.e2e.json", - "exclude": "**/node_modules/**" - } - ], - "test": { - "karma": { - "config": "./karma.conf.js" - } - }, - "defaults": { - "styleExt": "css", - "component": {} - } -} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml new file mode 100644 index 0000000..4d65c40 --- /dev/null +++ b/.github/workflows/release-please.yml @@ -0,0 +1,18 @@ +name: release-please + +on: + push: + branches: [main, master] + +permissions: + contents: write + pull-requests: write + +jobs: + release: + runs-on: ubuntu-latest + steps: + - uses: googleapis/release-please-action@v4 + with: + config-file: .release-please-config.json + manifest-file: .release-please-manifest.json diff --git a/.github/workflows/tauri-release.yml b/.github/workflows/tauri-release.yml new file mode 100644 index 0000000..4ff5be1 --- /dev/null +++ b/.github/workflows/tauri-release.yml @@ -0,0 +1,46 @@ +name: tauri-release + +on: + release: + types: [published] + +permissions: + contents: write + +jobs: + build: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: npm + + - name: Install JS dependencies + run: npm ci + + - uses: dtolnay/rust-toolchain@stable + + - name: Install Linux dependencies + if: runner.os == 'Linux' + run: | + sudo apt-get update + sudo apt-get install -y \ + libwebkit2gtk-4.1-dev \ + libgtk-3-dev \ + librsvg2-dev \ + patchelf + + - uses: tauri-apps/tauri-action@v0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + releaseId: ${{ github.event.release.id }} diff --git a/.gitignore b/.gitignore index eabf65e..4d60a13 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,10 @@ # dependencies /node_modules +# Angular CLI / Vite caches +/.angular/ +/.ng-tmp/ + # IDEs and editors /.idea .project @@ -35,10 +39,6 @@ yarn-error.log testem.log /typings -# e2e -/e2e/*.js -/e2e/*.map - # System Files .DS_Store Thumbs.db diff --git a/.release-please-config.json b/.release-please-config.json new file mode 100644 index 0000000..ceeb061 --- /dev/null +++ b/.release-please-config.json @@ -0,0 +1,14 @@ +{ + "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json", + "release-type": "node", + "packages": { + ".": { + "package-name": "sms-backup-viewer", + "extra-files": [ + "src-tauri/tauri.conf.json", + "src-tauri/Cargo.toml", + "src/app/version.ts" + ] + } + } +} diff --git a/.release-please-manifest.json b/.release-please-manifest.json new file mode 100644 index 0000000..c84411f --- /dev/null +++ b/.release-please-manifest.json @@ -0,0 +1,3 @@ +{ + ".": "0.26.0" +} diff --git a/.travis.yml b/.travis.yml index 4861c5c..49ebc40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ before_script: - npm install -g @angular/cli script: - - ng build --prod --bh /sms-backup-reader-2/ + - ng build --prod --bh /sms-backup-viewer/ # Workaround for GH Pages: copy index.html to 404.html before_deploy: @@ -21,5 +21,5 @@ deploy: github-token: $GITHUB_TOKEN # Set in travis-ci.org dashboard, marked secure keep-history: true on: - repo: devadvance/sms-backup-reader-2 + repo: SmokeHound/sms-backup-viewer tags: true diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6c2ff60 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "githubPullRequests.ignoredPullRequestBranches": [ + "master" + ] +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..91204cd --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,288 @@ +# Changelog + +## [0.26.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.25.0...sms-backup-viewer-v0.26.0) (2026-01-23) + + +### Features + +* enhance settings UI with improved layout and styling for storage stats ([d9902f9](https://github.com/SmokeHound/sms-backup-viewer/commit/d9902f9a9716ef7fafce5cf3d0f30d045ace9ee0)) + +## [0.25.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.24.0...sms-backup-viewer-v0.25.0) (2026-01-23) + + +### Features + +* add logging functionality and enhance UI components for better user experience ([798ecd4](https://github.com/SmokeHound/sms-backup-viewer/commit/798ecd46a7e0b64c482e7497f81235ba83c15149)) + +## [0.24.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.23.2...sms-backup-viewer-v0.24.0) (2026-01-22) + + +### Features + +* enhance join backups UI with back button and improved layout ([3ad2739](https://github.com/SmokeHound/sms-backup-viewer/commit/3ad2739f70a280db6d90bb9a00e9bde806371c8b)) + + +### Bug Fixes + +* update version information to 0.23.2 and adjust build time ([3ad2739](https://github.com/SmokeHound/sms-backup-viewer/commit/3ad2739f70a280db6d90bb9a00e9bde806371c8b)) + +## [0.23.2](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.23.1...sms-backup-viewer-v0.23.2) (2026-01-22) + + +### Bug Fixes + +* update file display and version information ([854f496](https://github.com/SmokeHound/sms-backup-viewer/commit/854f496d87acf850203cbffe1baa880d8c93d10c)) + +## [0.23.1](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.23.0...sms-backup-viewer-v0.23.1) (2026-01-22) + + +### Bug Fixes + +* enhance build time display and update version information ([13cdd6b](https://github.com/SmokeHound/sms-backup-viewer/commit/13cdd6bd91316b9d54981dac8c13067f03ff19c0)) +* update build time and git commit in version file ([810ee58](https://github.com/SmokeHound/sms-backup-viewer/commit/810ee58a24a031b4bc7e21abbcf98f4b9d9d5029)) + +## [0.23.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.22.1...sms-backup-viewer-v0.23.0) (2026-01-21) + + +### Features + +* enhance SmsStoreService to use NgZone for immediate change detection in event broadcasting ([60968be](https://github.com/SmokeHound/sms-backup-viewer/commit/60968beb7a29d6af8182d31789035fd61d375c38)) + + +### Bug Fixes + +* enhance contact list component to ensure proper Angular zone handling for IndexedDB promises ([4be9406](https://github.com/SmokeHound/sms-backup-viewer/commit/4be9406bbd8c2ba9dd1a54eb073b5d3c596faf97)) +* update Tauri imports to avoid Vite resolution issues and ensure proper runtime behavior ([60968be](https://github.com/SmokeHound/sms-backup-viewer/commit/60968beb7a29d6af8182d31789035fd61d375c38)) + +## [0.22.1](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.22.0...sms-backup-viewer-v0.22.1) (2026-01-21) + + +### Bug Fixes + +* update Tauri plugin import to use runtime-assembled path for better compatibility with Vite builds ([3069582](https://github.com/SmokeHound/sms-backup-viewer/commit/30695828676007f258a61f98017ce4286266054d)) + +## [0.22.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.21.0...sms-backup-viewer-v0.22.0) (2026-01-21) + + +### Features + +* implement Tauri runtime detection for native file picker support ([af1151f](https://github.com/SmokeHound/sms-backup-viewer/commit/af1151f48c79818d69e9bbe1a8784aae3b85d5ea)) + +## [0.21.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.20.0...sms-backup-viewer-v0.21.0) (2026-01-21) + + +### Features + +* add About dialog component with version and build info display ([8a3d4c7](https://github.com/SmokeHound/sms-backup-viewer/commit/8a3d4c7efd90e31f124cceda203f0a0393c18ebb)) +* add Help button with keyboard shortcut to open About dialog ([46fd281](https://github.com/SmokeHound/sms-backup-viewer/commit/46fd2818d45f3c1b9535bd3e5be4f41fb18532cb)) + +## [0.20.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.19.0...sms-backup-viewer-v0.20.0) (2026-01-20) + + +### Features + +* automate version management with update-version script and update version file ([48cca5e](https://github.com/SmokeHound/sms-backup-viewer/commit/48cca5e99b97051042901e11df5e27f53eec4794)) + +## [0.19.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.18.0...sms-backup-viewer-v0.19.0) (2026-01-20) + + +### Features + +* enhance file handling with error management and detail toggling in join backups ([3e64f82](https://github.com/SmokeHound/sms-backup-viewer/commit/3e64f8228f25fd51236a0a263a46be89d691f610)) +* update smsImportMode default to 'tauri' and enhance option descriptions for clarity ([b8eb451](https://github.com/SmokeHound/sms-backup-viewer/commit/b8eb45153b07a86b759cc25ef751f909120986a9)) + +## [0.18.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.17.0...sms-backup-viewer-v0.18.0) (2026-01-20) + + +### Features + +* Add new input source classes and value parsers for XML processing ([74b5f53](https://github.com/SmokeHound/sms-backup-viewer/commit/74b5f538657dbc937c36a9a135c35eea8ff0769a)) +* add XMLParser, node2json, and XmlNode classes for XML parsing functionality ([31eb1cb](https://github.com/SmokeHound/sms-backup-viewer/commit/31eb1cbb880f08a30b953a8cff7000545a0356ef)) + +## [0.17.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.16.0...sms-backup-viewer-v0.17.0) (2026-01-19) + + +### Features + +* add toast notifications for user feedback and implement Tauri-native file saving ([3c3a39f](https://github.com/SmokeHound/sms-backup-viewer/commit/3c3a39f6f43437b17041473240c9d9e4e059e856)) + +## [0.16.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.15.0...sms-backup-viewer-v0.16.0) (2026-01-19) + + +### Features + +* implement adaptive virtual scroll item size and optimize message fetching performance ([169f298](https://github.com/SmokeHound/sms-backup-viewer/commit/169f29804c276ffa832dab63261389fb27e63608)) + +## [0.15.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.14.0...sms-backup-viewer-v0.15.0) (2026-01-19) + + +### Features + +* add Angular CDK for virtual scrolling and implement lazy loading in message list ([89dc367](https://github.com/SmokeHound/sms-backup-viewer/commit/89dc36762f7165e32e0dac4f8e3905a9402c065a)) + +## [0.14.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.13.0...sms-backup-viewer-v0.14.0) (2026-01-19) + + +### Features + +* update file upload button styles for Tauri integration ([1212d88](https://github.com/SmokeHound/sms-backup-viewer/commit/1212d8831213f4fce2a71e9e93f6dde6e47382cd)) + +## [0.13.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.12.0...sms-backup-viewer-v0.13.0) (2026-01-19) + + +### Features + +* adjust margin and font weight in settings component for improved layout ([20f62e6](https://github.com/SmokeHound/sms-backup-viewer/commit/20f62e6c0ce9f8c499175776d98f2e7e75b09810)) +* increase window width to improve user interface in SMS Backup Viewer ([4b7934d](https://github.com/SmokeHound/sms-backup-viewer/commit/4b7934d1d2b39bc3bfd3dd883160471074bc04cf)) +* remove unnecessary descriptions from settings and sms loader components ([44befb4](https://github.com/SmokeHound/sms-backup-viewer/commit/44befb41713895c159b3cd693606769c08218b2c)) +* update sms-backup-viewer version to 0.12.0 in Cargo.lock ([99adbc1](https://github.com/SmokeHound/sms-backup-viewer/commit/99adbc12212ed8670ba15ffd5924e169e8581345)) +* update version to 0.12.0 and enhance footer layout with version display ([1bdd654](https://github.com/SmokeHound/sms-backup-viewer/commit/1bdd654fe2dd9c9cb96bcb8a26fdfb6ad6dbbf92)) + +## [0.12.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.11.0...sms-backup-viewer-v0.12.0) (2026-01-18) + + +### Features + +* refine Tauri import mode handling and enhance UI for file path actions ([ebe20eb](https://github.com/SmokeHound/sms-backup-viewer/commit/ebe20eb167192c890865ddc78f0031518a73acb1)) + +## [0.11.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.10.0...sms-backup-viewer-v0.11.0) (2026-01-17) + + +### Features + +* update version to 0.10.0 and enhance Tauri detection logic ([365083b](https://github.com/SmokeHound/sms-backup-viewer/commit/365083be54cd4c9c10286085c0c819965ece525d)) + +## [0.10.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.9.0...sms-backup-viewer-v0.10.0) (2026-01-17) + + +### Features + +* enhance message list component with auto-loading of older messages and scroll handling ([cd2594f](https://github.com/SmokeHound/sms-backup-viewer/commit/cd2594fc563a15f2911022475782ff9e2e43d57f)) +* update version to 0.10.0 and enhance settings with advanced import/export options ([686beaa](https://github.com/SmokeHound/sms-backup-viewer/commit/686beaace4a9a3b7d0db915c551ceeadfad65045)) + +## [0.9.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.8.0...sms-backup-viewer-v0.9.0) (2026-01-17) + + +### Features + +* implement loading older messages functionality with pagination support ([b264cfc](https://github.com/SmokeHound/sms-backup-viewer/commit/b264cfca4ade0f00e73c373e789a7213e8dfd3ed)) + +## [0.8.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.7.1...sms-backup-viewer-v0.8.0) (2026-01-17) + + +### Features + +* add button to load SMS backup from Tauri path with file picker integration ([6b60a54](https://github.com/SmokeHound/sms-backup-viewer/commit/6b60a540221fbc48c3419f5ecdcc049df8598207)) + +## [0.7.1](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.7.0...sms-backup-viewer-v0.7.1) (2026-01-17) + + +### Bug Fixes + +* add foldline and camelcase as allowed CommonJS dependencies in angular.json ([384b012](https://github.com/SmokeHound/sms-backup-viewer/commit/384b012537636a7012b9e654598b0d96dd351096)) +* add Tauri API integration and improve detection logic in SmsLoaderComponent ([6c6cf8a](https://github.com/SmokeHound/sms-backup-viewer/commit/6c6cf8aedf68a318bd9b63401c61e62cc34d56dd)) +* add Tauri development configuration and update start script ([17071e7](https://github.com/SmokeHound/sms-backup-viewer/commit/17071e7d033c1976f7b509dca517323db48084e6)) +* adjust min-height for settings container to ensure proper layout ([c449a77](https://github.com/SmokeHound/sms-backup-viewer/commit/c449a77bb19eac431d0f4fd397166b97f684a32d)) +* defer loading vCard library until contacts are loaded in VcfStoreService ([a3a1818](https://github.com/SmokeHound/sms-backup-viewer/commit/a3a1818938ee466443a732b46755302f15f8e78f)) +* optimize ngFor performance with trackBy for contacts and messages ([30c6a89](https://github.com/SmokeHound/sms-backup-viewer/commit/30c6a89ade03c6da7842d22fabb53ac7043d54e7)) +* remove obsolete app package and add sms-backup-viewer package with dependencies ([ced2a47](https://github.com/SmokeHound/sms-backup-viewer/commit/ced2a4760bdcf4dcb5324df8903b1d574adceb2d)) +* update build configuration for Tauri integration and adjust index file settings ([b0db603](https://github.com/SmokeHound/sms-backup-viewer/commit/b0db603ee7b25c57a8bc7d9d20ea745f3ccc73e0)) +* update package name, version, and description in Cargo.toml ([fc42259](https://github.com/SmokeHound/sms-backup-viewer/commit/fc42259d6d8af952f70b785b67deceeec9733638)) + +## [0.7.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.6.0...sms-backup-viewer-v0.7.0) (2026-01-17) + + +### Features + +* add help text for clearing stored SMS messages and integrate VcfStoreService for contact management ([43ae0cc](https://github.com/SmokeHound/sms-backup-viewer/commit/43ae0cc5f4b2cdf2c21120645263ba32d8d25dcd)) + + +### Bug Fixes + +* align text in mdl-layout-title for improved readability ([bdf6bf9](https://github.com/SmokeHound/sms-backup-viewer/commit/bdf6bf99283f74ec23dff4aa6ebc2a8f7267345a)) +* improve error messages for large file uploads in SmsLoaderComponent ([d3d2447](https://github.com/SmokeHound/sms-backup-viewer/commit/d3d244773095e80a079370a65844b053c50c6dcb)) + +## [0.6.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.5.0...sms-backup-viewer-v0.6.0) (2026-01-17) + + +### Features + +* add IndexedDB support for message persistence and enhance settings UI ([28e4394](https://github.com/SmokeHound/sms-backup-viewer/commit/28e439447ec4589a142b34a45e4c107e075dd117)) +* integrate Dexie for IndexedDB support and refactor message handling ([d1f7855](https://github.com/SmokeHound/sms-backup-viewer/commit/d1f78553c2c3dd1b616d5ae1c4899a2f9b189c3e)) + + +### Bug Fixes + +* update handling of large XML files and improve user guidance for Tauri mode ([4b73f94](https://github.com/SmokeHound/sms-backup-viewer/commit/4b73f94935a99dbeafa132135c2fd4625ef1d3b8)) + +## [0.5.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-backup-viewer-v0.4.0...sms-backup-viewer-v0.5.0) (2026-01-16) + + +### Features + +* add documentation for exporting MMS media as separate files ([dd21848](https://github.com/SmokeHound/sms-backup-viewer/commit/dd2184809b07767a293fe2e6aaebd9a2460ec022)) +* add features array to Tauri dependencies for improved configuration ([56cb47b](https://github.com/SmokeHound/sms-backup-viewer/commit/56cb47b7a7aac00d456bb27ced7822066003314f)) +* add Material Design Lite dependencies and update configurations ([d2143f2](https://github.com/SmokeHound/sms-backup-viewer/commit/d2143f2a82f7322578baa56ea600869665a2f385)) +* add release workflows and update project name to SMS Backup Viewer ([640fd14](https://github.com/SmokeHound/sms-backup-viewer/commit/640fd143ec6f10c871cd4e7ced85981bcacc9751)) +* add support for exporting MMS media as separate files and implement related functionality ([2a5e02c](https://github.com/SmokeHound/sms-backup-viewer/commit/2a5e02cfb647a707f156f7d6e6ae7429f24ec309)) +* add support for loading multiple SMS backup files and handle large file warnings ([5a27d60](https://github.com/SmokeHound/sms-backup-viewer/commit/5a27d6041988c9a4745011798983d5c64f832ff6)) +* add Tauri build configuration to angular.json ([1768259](https://github.com/SmokeHound/sms-backup-viewer/commit/176825928fd0bf7c87164c8d227ef385cdcb27b9)) +* add Tauri preflight check script and update documentation for setup ([5928283](https://github.com/SmokeHound/sms-backup-viewer/commit/592828344aaaa96f905c9b421a370c026fc3a106)) +* add Tauri support for desktop app packaging and configuration ([a534ce6](https://github.com/SmokeHound/sms-backup-viewer/commit/a534ce60524cffb992b87128803601f706d98fe6)) +* enhance file upload UI with improved layout and spacing ([c8cfce7](https://github.com/SmokeHound/sms-backup-viewer/commit/c8cfce7738cf97f841c15069d782752ee1c561b7)) +* enhance production build process and improve documentation ([055f20f](https://github.com/SmokeHound/sms-backup-viewer/commit/055f20fbe373228a10d970b3debe81f9558a2961)) +* enhance styling and layout across components with improved variables and structure ([fc493b1](https://github.com/SmokeHound/sms-backup-viewer/commit/fc493b118654de8417128cd0ed647ad6f4bcea06)) +* enhance XML and VCF file loading with error handling and improved user feedback ([9ca570a](https://github.com/SmokeHound/sms-backup-viewer/commit/9ca570a8f296f957b3e53e84d89889083252b318)) +* implement CSV export functionality for messages and contacts ([5eb7876](https://github.com/SmokeHound/sms-backup-viewer/commit/5eb7876a6da8bf9ca2be64c7e1ddd0151c5f6574)) +* implement loader status updates for SMS and VCF components with new status bar ([dfe15b4](https://github.com/SmokeHound/sms-backup-viewer/commit/dfe15b4ca56f5694a24c83bbc3b4794e203736c8)) +* implement Tauri support for SMS backup parsing and enhance UI for file loading ([3201572](https://github.com/SmokeHound/sms-backup-viewer/commit/3201572025fbcda5bd329c6ba44a2bb84395a4b1)) +* improve header and footer styles with enhanced loader controls and visibility adjustments ([9e24eeb](https://github.com/SmokeHound/sms-backup-viewer/commit/9e24eebdaa2462a596a6cf20f973f39ff2a37739)) +* refactor XML element retrieval for improved robustness and error handling ([9ef829a](https://github.com/SmokeHound/sms-backup-viewer/commit/9ef829ab273129daf1152262c950bb8d143180b6)) +* update country default to AU and enhance country handling in SMS and VCF loaders ([5aea81b](https://github.com/SmokeHound/sms-backup-viewer/commit/5aea81be506de9713c8458d30d18566972c162d7)) +* update styles for improved UI consistency and responsiveness ([21b019d](https://github.com/SmokeHound/sms-backup-viewer/commit/21b019d0f79bd16544f6f2cf36156b905f165427)) + + +### Bug Fixes + +* correct action reference in release workflow ([ff3ea2f](https://github.com/SmokeHound/sms-backup-viewer/commit/ff3ea2fa5eadd493563c53c2af76f06a28150d11)) +* update @angular-devkit/architect version and remove duplicate entries ([be7fc32](https://github.com/SmokeHound/sms-backup-viewer/commit/be7fc325f3ca8c6014f0c629d1ccba79a74767d6)) +* update copyright year to 2026 in footer ([73b97aa](https://github.com/SmokeHound/sms-backup-viewer/commit/73b97aa23f2d2ce457e711a99097455e4dc7d7d5)) +* update package name and paths to reflect new branding as sms-backup-viewer ([12a926e](https://github.com/SmokeHound/sms-backup-viewer/commit/12a926eb586600f741c108be1ce1f6dd706af9a9)) + +## [0.4.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-back-reader-2-v0.3.0...sms-back-reader-2-v0.4.0) (2026-01-16) + + +### Features + +* enhance styling and layout across components with improved variables and structure ([fc493b1](https://github.com/SmokeHound/sms-backup-viewer/commit/fc493b118654de8417128cd0ed647ad6f4bcea06)) +* update styles for improved UI consistency and responsiveness ([21b019d](https://github.com/SmokeHound/sms-backup-viewer/commit/21b019d0f79bd16544f6f2cf36156b905f165427)) + +## [0.3.0](https://github.com/SmokeHound/sms-backup-viewer/compare/sms-back-reader-2-v0.2.0...sms-back-reader-2-v0.3.0) (2026-01-16) + + +### Features + +* add documentation for exporting MMS media as separate files ([dd21848](https://github.com/SmokeHound/sms-backup-viewer/commit/dd2184809b07767a293fe2e6aaebd9a2460ec022)) +* add features array to Tauri dependencies for improved configuration ([56cb47b](https://github.com/SmokeHound/sms-backup-viewer/commit/56cb47b7a7aac00d456bb27ced7822066003314f)) +* add Material Design Lite dependencies and update configurations ([d2143f2](https://github.com/SmokeHound/sms-backup-viewer/commit/d2143f2a82f7322578baa56ea600869665a2f385)) +* add release workflows and update project name to SMS Backup Viewer ([640fd14](https://github.com/SmokeHound/sms-backup-viewer/commit/640fd143ec6f10c871cd4e7ced85981bcacc9751)) +* add support for exporting MMS media as separate files and implement related functionality ([2a5e02c](https://github.com/SmokeHound/sms-backup-viewer/commit/2a5e02cfb647a707f156f7d6e6ae7429f24ec309)) +* add support for loading multiple SMS backup files and handle large file warnings ([5a27d60](https://github.com/SmokeHound/sms-backup-viewer/commit/5a27d6041988c9a4745011798983d5c64f832ff6)) +* add Tauri build configuration to angular.json ([1768259](https://github.com/SmokeHound/sms-backup-viewer/commit/176825928fd0bf7c87164c8d227ef385cdcb27b9)) +* add Tauri preflight check script and update documentation for setup ([5928283](https://github.com/SmokeHound/sms-backup-viewer/commit/592828344aaaa96f905c9b421a370c026fc3a106)) +* add Tauri support for desktop app packaging and configuration ([a534ce6](https://github.com/SmokeHound/sms-backup-viewer/commit/a534ce60524cffb992b87128803601f706d98fe6)) +* enhance file upload UI with improved layout and spacing ([c8cfce7](https://github.com/SmokeHound/sms-backup-viewer/commit/c8cfce7738cf97f841c15069d782752ee1c561b7)) +* enhance production build process and improve documentation ([055f20f](https://github.com/SmokeHound/sms-backup-viewer/commit/055f20fbe373228a10d970b3debe81f9558a2961)) +* enhance XML and VCF file loading with error handling and improved user feedback ([9ca570a](https://github.com/SmokeHound/sms-backup-viewer/commit/9ca570a8f296f957b3e53e84d89889083252b318)) +* implement CSV export functionality for messages and contacts ([5eb7876](https://github.com/SmokeHound/sms-backup-viewer/commit/5eb7876a6da8bf9ca2be64c7e1ddd0151c5f6574)) +* implement loader status updates for SMS and VCF components with new status bar ([dfe15b4](https://github.com/SmokeHound/sms-backup-viewer/commit/dfe15b4ca56f5694a24c83bbc3b4794e203736c8)) +* implement Tauri support for SMS backup parsing and enhance UI for file loading ([3201572](https://github.com/SmokeHound/sms-backup-viewer/commit/3201572025fbcda5bd329c6ba44a2bb84395a4b1)) +* improve header and footer styles with enhanced loader controls and visibility adjustments ([9e24eeb](https://github.com/SmokeHound/sms-backup-viewer/commit/9e24eebdaa2462a596a6cf20f973f39ff2a37739)) +* refactor XML element retrieval for improved robustness and error handling ([9ef829a](https://github.com/SmokeHound/sms-backup-viewer/commit/9ef829ab273129daf1152262c950bb8d143180b6)) +* update country default to AU and enhance country handling in SMS and VCF loaders ([5aea81b](https://github.com/SmokeHound/sms-backup-viewer/commit/5aea81be506de9713c8458d30d18566972c162d7)) + + +### Bug Fixes + +* update @angular-devkit/architect version and remove duplicate entries ([be7fc32](https://github.com/SmokeHound/sms-backup-viewer/commit/be7fc325f3ca8c6014f0c629d1ccba79a74767d6)) +* update copyright year to 2026 in footer ([73b97aa](https://github.com/SmokeHound/sms-backup-viewer/commit/73b97aa23f2d2ce457e711a99097455e4dc7d7d5)) diff --git a/DEVELOPING.md b/DEVELOPING.md index c4d74cf..1a7fadc 100644 --- a/DEVELOPING.md +++ b/DEVELOPING.md @@ -1,29 +1,127 @@ -# Developing SMS Backup Reader 2 +# Developing SMS Backup Viewer -Note: These docs were generated by the Angular CLI and moved to a separate file. +This repo uses Angular (via the locally-installed Angular CLI) and Vitest. -This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.7.3. +## Prerequisites + +- Node.js (a recent LTS release is recommended) +- npm + +Install dependencies: + +```bash +npm install +``` ## Development server -Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. +Run `npm start` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. + +If you prefer calling Angular CLI directly without a global install, use `npx ng ...`. ## Code scaffolding -Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`. +Run `npx ng generate component component-name` to generate a new component. + +You can also use: + +```bash +npx ng generate directive|pipe|service|class|guard|interface|enum|module ... +``` ## Build -Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. +Run `npm run build` to build the project. -## Running unit tests +Build artifacts are written to `dist/`. + +Useful variants: + +```bash +npm run watch +npm run build -- --configuration production +``` + +## Preview the production build + +Do **not** open the built `dist/.../browser/index.html` directly with your browser (a `file://` URL). Modern browsers will block loading the built JS bundles (e.g. `main.js`) due to CORS / origin restrictions. + +Instead, serve the build output over HTTP: + +```bash +npm run build -- --configuration production +npm run preview:dist +``` + +Then open `http://localhost:8080/`. + +Alternative: if you just want the dev server with production settings (not the `dist/` output), run: + +```bash +npm run start:prod +``` + +## Handling very large backups + +This app loads backups in the browser and currently parses XML by reading the entire file as text. + +- Multi-GB backups (common when exporting MMS media inline) are likely to fail in the browser. +- Recommended workaround: export **SMS only** / **no media**, or split the export. +- The SMS loader supports selecting **multiple** `.xml` files at once; it will merge them into a single message list. -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). +If you need to load a single multi-GB XML file, use the desktop build (Tauri): the SMS loader includes a Tauri mode that parses by file path using a streaming XML parser. -## Running end-to-end tests +## Exporting MMS media as separate files + +When exporting from the message list, you can enable **Export MMS media as separate files (creates a .zip)**. + +- Output is a ZIP that contains `messages.csv` plus extracted media files under `media//...`. +- `bodyHtml` in the CSV is rewritten so `` becomes ``. +- This is useful to avoid huge CSV files when a backup contains inline/base64 MMS images. + +## Desktop app (Tauri) + +This repo can be packaged as a native desktop app using Tauri. + +### Windows prerequisites + +- Rust toolchain (MSVC): install via `https://rustup.rs/` +- Microsoft C++ Build Tools (Visual Studio Build Tools) +- WebView2 Runtime (usually already installed on Windows 10/11) + +### Run the desktop app in dev mode + +This starts the Angular dev server and launches the Tauri window. + +If you hit errors like `cargo metadata ... program not found`, run the preflight check first: + +```bash +npm run tauri:check +``` + +```bash +npm run tauri:dev +``` + +Note: `tauri:dev` uses `npm run start:tauri` under the hood so the dev server uses the Tauri index file (no Google Tag Manager). + +### Build an installable desktop bundle + +```bash +npm run tauri:build +``` + +The build will run the Angular `tauri` configuration (see `angular.json`) and then package the app. + +### Offline notes + +- Material Icons are bundled locally (no Google Fonts dependency). +- The desktop build uses `src/index.tauri.html` (no Google Tag Manager). + +## Running unit tests -Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). +Run `npm test` (or `npm run test:watch`) to execute the unit tests via Vitest. ## Further help -To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI README](https://github.com/angular/angular-cli/blob/master/README.md). +To get more help on the Angular CLI use `npx ng help`. diff --git a/LICENSE b/LICENSE index 2217c60..88a9c06 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright 2018 Matt Joseph +Copyright 2026 Josh Burt Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 1a9dbc0..f33620b 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,55 @@ -# SMS Backup Reader 2 - -[![Build Status](https://travis-ci.org/devadvance/sms-backup-reader-2.svg?branch=master)](https://travis-ci.org/devadvance/sms-backup-reader-2) +# SMS Backup Viewer This is an Angular-based web app designed to read the XML backup files produced by the Android app SMS Backup & Restore by Ritesh. It is designed to work in modern browsers, including Chrome, Firefox, Edge, and Safari. This app works locally and your SMS data **does not** leave your machine. -This app is currently in alpha. +## Quick start + +```bash +npm install +npm start +``` + +Then open `http://localhost:4200/`. + +Note: if `ng` is not found on your machine, that’s expected unless you installed Angular CLI globally. Use the project scripts (`npm start`, `npm run build`, etc.) or `npx ng ...`. + +If you build the app (`npm run build`) and then open the generated `dist/.../index.html` via `file://`, your browser will likely block the JS bundles (CORS). To preview the built output, run `npm run preview:dist` and open `http://localhost:8080/`. + +## Large backups / split files -**You can access the app here: [http://mattj.io/sms-backup-reader-2/](http://mattj.io/sms-backup-reader-2/)** +Very large XML backups (especially with MMS media) may be too large for the browser to load/parse as a single file. + +If you have a multi-GB backup (e.g. 2+ GB), use the desktop build (Tauri) and load the file by path. Browsers generally cannot handle parsing a multi-GB XML file as a single in-memory string. + +- Prefer exporting **SMS only** / **no media** when possible. +- If you need to split your export, you can select **multiple** `.xml` files at once in the SMS loader — they will be merged into a single combined message list. ## Features -* Load SMS backup files produced by and Android app SMS Backup & Restore by Ritesh +* Load SMS backup files produced by the Android app SMS Backup & Restore by Ritesh * International support (non-latin character) and emoji support -* MSS support (thanks to JLTRY) -* VCF support (thanks to JLTRY) +* MMS support +* VCF support +* Export messages and contacts to CSV +* Export MMS media embedded in message HTML (via CSV export including `bodyHtml`) +* Export MMS media as separate files (ZIP export) ## Issues -* Styles need serious work and overall UX is clunky -* All data is loaded into JS memory, which means: -* Large backups (>3,000 SMS) will freeze the UI until they are loaded -* Loading specific conversations may be slow and freeze the UI -* App breaks when using settings after loading data - -If you encounter other issues, please add the issues here: [https://github.com/devadvance/sms-backup-reader-2/issues](https://github.com/devadvance/sms-backup-reader-2/issues). +If you encounter issues, please add them to the issues section. ## Roadmap (no timeline defined) -* Export SMS to CSV or TXT -* Support for exporting media from MMS -* More? +* Desktop app.(Work in progress) +* Request any features/improvements you would like to be added. + +## Development + +See [DEVELOPING.md](DEVELOPING.md) for development workflows. + +Want a desktop app? This repo includes a Tauri wrapper; see the Desktop (Tauri) section in [DEVELOPING.md](DEVELOPING.md). -## Note about emoji and text handing in this app (mostly for devs) +## Note about emoji and text handling in this app (mostly for devs) SMS Backup & Restore saves emojis and other special characters in a very interesting way. @@ -44,4 +62,4 @@ Likely, it goes back to how characters are encoded in SMS. ## License -SMS Backup Reader 2 is made available under the MIT license. See the LICENSE file for details. \ No newline at end of file +SMS Backup Viewer is made available under the MIT license. See the LICENSE file for details. diff --git a/angular.json b/angular.json new file mode 100644 index 0000000..50f8ae3 --- /dev/null +++ b/angular.json @@ -0,0 +1,135 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "cli": { + "packageManager": "npm", + "analytics": false + }, + "projects": { + "sms-backup-viewer": { + "projectType": "application", + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular/build:application", + "options": { + "outputPath": "dist/sms-backup-viewer", + "browser": "src/main.ts", + "index": "src/index.html", + "tsConfig": "tsconfig.app.json", + "allowedCommonJsDependencies": [ + "awesome-phonenumber", + "material-design-lite", + "vcf", + "jszip", + "foldline", + "camelcase" + ], + "assets": [ + "src/favicon.ico", + "src/assets" + ], + "styles": [ + "node_modules/material-icons/iconfont/material-icons.css", + "node_modules/material-design-lite/dist/material.light_blue-green.min.css", + "src/styles.css" + ], + "scripts": [ + "node_modules/material-design-lite/material.min.js" + ] + }, + "configurations": { + "production": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "budgets": [ + { + "type": "initial", + "maximumWarning": "1.5MB", + "maximumError": "3MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "tauri": { + "fileReplacements": [ + { + "replace": "src/environments/environment.ts", + "with": "src/environments/environment.prod.ts" + } + ], + "index": { + "input": "src/index.tauri.html", + "output": "index.html" + }, + "outputHashing": "all", + "budgets": [ + { + "type": "initial", + "maximumWarning": "1.5MB", + "maximumError": "3MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ] + }, + "tauriDev": { + "index": "src/index.tauri.html", + "optimization": false, + "extractLicenses": false, + "sourceMap": true, + "outputHashing": "none" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular/build:dev-server", + "configurations": { + "production": { + "buildTarget": "sms-backup-viewer:build:production" + }, + "tauri": { + "buildTarget": "sms-backup-viewer:build:tauri" + }, + "tauriDev": { + "buildTarget": "sms-backup-viewer:build:tauriDev" + }, + "development": { + "buildTarget": "sms-backup-viewer:build:development" + } + }, + "defaultConfiguration": "development" + }, + "test": { + "builder": "@angular/build:unit-test", + "options": { + "runner": "vitest", + "runnerConfig": true, + "tsConfig": "tsconfig.spec.json", + "watch": false + } + } + } + } + } +} diff --git a/e2e/app.e2e-spec.ts b/e2e/app.e2e-spec.ts deleted file mode 100644 index ca01b49..0000000 --- a/e2e/app.e2e-spec.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { AppPage } from './app.po'; - -describe('sms-back-reader2 App', () => { - let page: AppPage; - - beforeEach(() => { - page = new AppPage(); - }); - - it('should display welcome message', () => { - page.navigateTo(); - expect(page.getParagraphText()).toEqual('Welcome to app!'); - }); -}); diff --git a/e2e/app.po.ts b/e2e/app.po.ts deleted file mode 100644 index 82ea75b..0000000 --- a/e2e/app.po.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { browser, by, element } from 'protractor'; - -export class AppPage { - navigateTo() { - return browser.get('/'); - } - - getParagraphText() { - return element(by.css('app-root h1')).getText(); - } -} diff --git a/e2e/tsconfig.e2e.json b/e2e/tsconfig.e2e.json deleted file mode 100644 index 1d9e5ed..0000000 --- a/e2e/tsconfig.e2e.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "extends": "../tsconfig.json", - "compilerOptions": { - "outDir": "../out-tsc/e2e", - "baseUrl": "./", - "module": "commonjs", - "target": "es5", - "types": [ - "jasmine", - "jasminewd2", - "node" - ] - } -} diff --git a/karma.conf.js b/karma.conf.js deleted file mode 100644 index a359c85..0000000 --- a/karma.conf.js +++ /dev/null @@ -1,35 +0,0 @@ -// Karma configuration file, see link for more information -// https://karma-runner.github.io/1.0/config/configuration-file.html - -module.exports = function (config) { - config.set({ - basePath: '', - frameworks: ['jasmine', '@angular/cli'], - plugins: [ - - require('karma-jasmine'), - require('karma-chrome-launcher'), - require('karma-jasmine-html-reporter'), - require('karma-coverage-istanbul-reporter'), - require('@angular/cli/plugins/karma') - ], - client:{ - clearContext: false // leave Jasmine Spec Runner output visible in browser - }, - coverageIstanbulReporter: { - reports: [ 'html', 'lcovonly' ], - fixWebpackSourcePaths: true - }, - angularCli: { - environment: 'dev' - }, - reporters: ['progress', 'kjhtml'], - port: 9876, - colors: true, - logLevel: config.LOG_INFO, - autoWatch: true, - browsers: ['Chrome'], - singleRun: false - }); - -}; diff --git a/package-lock.json b/package-lock.json index 664aafe..59c2ddb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12610 +1,9138 @@ { - "name": "sms-back-reader-2", - "version": "0.1.0", - "lockfileVersion": 1, + "name": "sms-backup-viewer", + "version": "0.26.0", + "lockfileVersion": 3, "requires": true, - "dependencies": { - "@angular-devkit/build-optimizer": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/build-optimizer/-/build-optimizer-0.3.2.tgz", - "integrity": "sha512-U0BCZtThq5rUfY08shHXpxe8ZhSsiYB/cJjUvAWRTs/ORrs8pbngS6xwseQws8d/vHoVrtqGD9GU9h8AmFRERQ==", + "packages": { + "": { + "name": "sms-backup-viewer", + "version": "0.26.0", + "license": "MIT", + "dependencies": { + "@angular/animations": "~21.1.0", + "@angular/common": "~21.1.0", + "@angular/compiler": "~21.1.0", + "@angular/core": "~21.1.0", + "@angular/forms": "~21.1.0", + "@angular/platform-browser": "~21.1.0", + "@angular/router": "~21.1.0", + "@tauri-apps/api": "^2.8.0", + "@tauri-apps/plugin-dialog": "^2.6.0", + "@tauri-apps/plugin-fs": "^2.4.5", + "awesome-phonenumber": "^2.2.5", + "dexie": "^4.2.1", + "fast-xml-parser": "^4.2.4", + "jszip": "^3.10.1", + "material-design-lite": "^1.3.0", + "material-icons": "^1.13.14", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "vcf": "^2.0.1" + }, + "devDependencies": { + "@angular/build": "~21.1.0", + "@angular/cdk": "~21.1.0", + "@angular/cli": "~21.1.0", + "@angular/compiler-cli": "~21.1.0", + "@tauri-apps/cli": "^2.9.6", + "@types/node": "^24.0.0", + "jsdom": "^27.1.0", + "typescript": "~5.9.2", + "vitest": "^4.0.8" + } + }, + "node_modules/@acemir/cssom": { + "version": "0.9.31", + "resolved": "https://registry.npmjs.org/@acemir/cssom/-/cssom-0.9.31.tgz", + "integrity": "sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@algolia/abtesting": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.12.2.tgz", + "integrity": "sha512-oWknd6wpfNrmRcH0vzed3UPX0i17o4kYLM5OMITyMVM2xLgaRbIafoxL0e8mcrNNb0iORCJA0evnNDKRYth5WQ==", "dev": true, - "requires": { - "loader-utils": "1.1.0", - "source-map": "0.5.7", - "typescript": "2.6.2", - "webpack-sources": "1.1.0" - }, + "license": "MIT", "dependencies": { - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true - } + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular-devkit/core": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-0.3.2.tgz", - "integrity": "sha512-zABk/iP7YX5SVbmK4e+IX7j2d0D37MQJQiKgWdV3JzfvVJhNJzddiirtT980pIafoq+KyvTgVwXtc+vnux0oeQ==", + "node_modules/@algolia/client-abtesting": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.46.2.tgz", + "integrity": "sha512-oRSUHbylGIuxrlzdPA8FPJuwrLLRavOhAmFGgdAvMcX47XsyM+IOGa9tc7/K5SPvBqn4nhppOCEz7BrzOPWc4A==", "dev": true, - "requires": { - "ajv": "5.5.2", - "chokidar": "1.7.0", - "rxjs": "5.5.7", - "source-map": "0.5.7" - }, + "license": "MIT", "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - } - } - }, - "@angular-devkit/schematics": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-0.3.2.tgz", - "integrity": "sha512-B6zZoqvHaTJy+vVdA6EtlxnCdGMa5elCa4j9lQLC3JI8DLvMXUWkCIPVbPzJ/GSRR9nsKWpvYMYaJyfBDUqfhw==", - "dev": true, - "requires": { - "@ngtools/json-schema": "1.2.0", - "rxjs": "5.5.7" - } - }, - "@angular/animations": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-5.2.9.tgz", - "integrity": "sha512-H/3fMs4PhYjKoA81II6D0PHifDrqlKet2u/EXzUBq3ehXby+N/0GBzqsBYwPeU5pTye7WPFfW+5sgoJpN8Ye6Q==", - "requires": { - "tslib": "1.9.0" - } - }, - "@angular/cli": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-1.7.3.tgz", - "integrity": "sha512-19sh0SbjneG7/R/FvZBfHsHqfIqyj4LQuXdddJKMCDM97UoHQTjfgrpRvBf3a3lR79wdLXchWJBD9Yc6ifosEA==", - "dev": true, - "requires": { - "@angular-devkit/build-optimizer": "0.3.2", - "@angular-devkit/core": "0.3.2", - "@angular-devkit/schematics": "0.3.2", - "@ngtools/json-schema": "1.2.0", - "@ngtools/webpack": "1.10.2", - "@schematics/angular": "0.3.2", - "@schematics/package-update": "0.3.2", - "ajv": "6.4.0", - "autoprefixer": "7.2.6", - "cache-loader": "1.2.2", - "chalk": "2.2.2", - "circular-dependency-plugin": "4.4.0", - "clean-css": "4.1.11", - "common-tags": "1.7.2", - "copy-webpack-plugin": "4.4.3", - "core-object": "3.1.5", - "denodeify": "1.2.1", - "ember-cli-string-utils": "1.1.0", - "extract-text-webpack-plugin": "3.0.2", - "file-loader": "1.1.11", - "fs-extra": "4.0.3", - "glob": "7.1.2", - "html-webpack-plugin": "2.30.1", - "istanbul-instrumenter-loader": "3.0.0", - "karma-source-map-support": "1.2.0", - "less": "2.7.3", - "less-loader": "4.1.0", - "license-webpack-plugin": "1.3.1", - "loader-utils": "1.1.0", - "lodash": "4.17.5", - "memory-fs": "0.4.1", - "minimatch": "3.0.4", - "node-modules-path": "1.0.1", - "node-sass": "4.8.3", - "nopt": "4.0.1", - "opn": "5.1.0", - "portfinder": "1.0.13", - "postcss": "6.0.21", - "postcss-import": "11.1.0", - "postcss-loader": "2.1.3", - "postcss-url": "7.3.1", - "raw-loader": "0.5.1", - "resolve": "1.6.0", - "rxjs": "5.5.7", - "sass-loader": "6.0.7", - "semver": "5.5.0", - "silent-error": "1.1.0", - "source-map-support": "0.4.18", - "style-loader": "0.19.1", - "stylus": "0.54.5", - "stylus-loader": "3.0.2", - "uglifyjs-webpack-plugin": "1.2.4", - "url-loader": "0.6.2", - "webpack": "3.11.0", - "webpack-dev-middleware": "1.12.2", - "webpack-dev-server": "2.11.2", - "webpack-merge": "4.1.2", - "webpack-sources": "1.1.0", - "webpack-subresource-integrity": "1.0.4" - } - }, - "@angular/common": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/common/-/common-5.2.9.tgz", - "integrity": "sha512-g2hPcI0fnT4TV+Fd+1IohjuqBxPvxwyH9IzTn8PkU9X2M+F6cHCUvHxL1sWI2sF8pYcaHzVjq9WClym10X36Lg==", - "requires": { - "tslib": "1.9.0" - } - }, - "@angular/compiler": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-5.2.9.tgz", - "integrity": "sha512-mN+ofInk8y/tk2TCJZx8RrGdOKdrfunoCair7tfDy4XoQJE90waGfaYWo07hYU+UYwLhrg19m2Czy6rIDciUJA==", - "requires": { - "tslib": "1.9.0" - } - }, - "@angular/compiler-cli": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-5.2.9.tgz", - "integrity": "sha512-LAEpL/6PAev3zwTow/43Atzv9AtKLAiLoS285X3EV1f80yQpYAmFRrPUtDlrIZdhZHBBv7CxnyCVpOLU3T8ohw==", - "dev": true, - "requires": { - "chokidar": "1.7.0", - "minimist": "1.2.0", - "reflect-metadata": "0.1.12", - "tsickle": "0.27.2" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular/core": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/core/-/core-5.2.9.tgz", - "integrity": "sha512-cvHBJGtasrIoARvbLFyHaOsiWKVwMNrrSTZLwrlyHP8oYzkDrE0qKGer6QCqyKt+51hF53cgWEffGzM/u/0wYg==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-analytics": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.46.2.tgz", + "integrity": "sha512-EPBN2Oruw0maWOF4OgGPfioTvd+gmiNwx0HmD9IgmlS+l75DatcBkKOPNJN+0z3wBQWUO5oq602ATxIfmTQ8bA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular/forms": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-5.2.9.tgz", - "integrity": "sha512-zyIOiZV/FAm1iVZWTk3Joz6Jt096hbhfDbBUrssmuiTKi9dU6rWG+Z4b88zStqulKe3HFVZkgdixWlminG8nKA==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-common": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.46.2.tgz", + "integrity": "sha512-Hj8gswSJNKZ0oyd0wWissqyasm+wTz1oIsv5ZmLarzOZAp3vFEda8bpDQ8PUhO+DfkbiLyVnAxsPe4cGzWtqkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.0.0" } }, - "@angular/http": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/http/-/http-5.2.9.tgz", - "integrity": "sha512-DKjgIk+Dp0Xv1ieG8LawvUnL4dYZp1KroAq5cfKuO9EojP0zM3tUvBtw2vbPLsHYma7g7ZMjOoAbzVxtmTBZqw==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-insights": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.46.2.tgz", + "integrity": "sha512-6dBZko2jt8FmQcHCbmNLB0kCV079Mx/DJcySTL3wirgDBUH7xhY1pOuUTLMiGkqM5D8moVZTvTdRKZUJRkrwBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular/language-service": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/language-service/-/language-service-5.2.9.tgz", - "integrity": "sha512-aaLnGpW9NBDkG0JYqUeGc+al1Jd1CY9yrs3mew53x5nByetQbIdZwpYm1hnSTw7LBEZBxfHTMw5EZD2YYTDmJw==", - "dev": true - }, - "@angular/platform-browser": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-5.2.9.tgz", - "integrity": "sha512-P6iviRTuLsLRuqtZNOO0fd4cjTo8DWsDCecwntUlI08R3kH5qeqvqarTzlw/4oD+wBzZY6bfb89JyY+n5XbX3Q==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-personalization": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.46.2.tgz", + "integrity": "sha512-1waE2Uqh/PHNeDXGn/PM/WrmYOBiUGSVxAWqiJIj73jqPqvfzZgzdakHscIVaDl6Cp+j5dwjsZ5LCgaUr6DtmA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular/platform-browser-dynamic": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-5.2.9.tgz", - "integrity": "sha512-8C3MtyguJKDTT8FcHIRDlBxswcIdpfugOf4S2t94pVedCr4h9w2da/lcfwJKUISw1aKjfA77Sl8TDUhoS8ymmQ==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-query-suggestions": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.46.2.tgz", + "integrity": "sha512-EgOzTZkyDcNL6DV0V/24+oBJ+hKo0wNgyrOX/mePBM9bc9huHxIY2352sXmoZ648JXXY2x//V1kropF/Spx83w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@angular/router": { - "version": "5.2.9", - "resolved": "https://registry.npmjs.org/@angular/router/-/router-5.2.9.tgz", - "integrity": "sha512-NtDbFK0EA1rfFc+5Dqd5mIv8E1Wcc5rDUnSty4cX2V+HxTEZvQ9DRdpO2Q0abWU5siXyqponuPHJzF08OVGyNA==", - "requires": { - "tslib": "1.9.0" + "node_modules/@algolia/client-search": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.46.2.tgz", + "integrity": "sha512-ZsOJqu4HOG5BlvIFnMU0YKjQ9ZI6r3C31dg2jk5kMWPSdhJpYL9xa5hEe7aieE+707dXeMI4ej3diy6mXdZpgA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@ngtools/json-schema": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.2.0.tgz", - "integrity": "sha512-pMh+HDc6mOjUO3agRfB1tInimo7hf67u+0Cska2bfXFe6oU7rSMnr5PLVtiZVgwMoBHpx/6XjBymvcnWPo2Uzg==", - "dev": true - }, - "@ngtools/webpack": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-1.10.2.tgz", - "integrity": "sha512-3u2zg2rarG3qNLSukBClGADWuq/iNn5SQtlSeAbfKzwBeyLGbF0gN1z1tVx1Bcr8YwFzR6NdRePQmJGcoqq1fg==", + "node_modules/@algolia/ingestion": { + "version": "1.46.2", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.46.2.tgz", + "integrity": "sha512-1Uw2OslTWiOFDtt83y0bGiErJYy5MizadV0nHnOoHFWMoDqWW0kQoMFI65pXqRSkVvit5zjXSLik2xMiyQJDWQ==", "dev": true, - "requires": { - "chalk": "2.2.2", - "enhanced-resolve": "3.4.1", - "loader-utils": "1.1.0", - "magic-string": "0.22.5", - "semver": "5.5.0", - "source-map": "0.5.7", - "tree-kill": "1.2.0", - "webpack-sources": "1.1.0" + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@schematics/angular": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-0.3.2.tgz", - "integrity": "sha512-Elrk0BA951s0ScFZU0AWrpUeJBYVR52DZ1QTIO5R0AhwEd1PW4olI8szPLGQlVW5Sd6H0FA/fyFLIvn2r9v6Rw==", + "node_modules/@algolia/monitoring": { + "version": "1.46.2", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.46.2.tgz", + "integrity": "sha512-xk9f+DPtNcddWN6E7n1hyNNsATBCHIqAvVGG2EAGHJc4AFYL18uM/kMTiOKXE/LKDPyy1JhIerrh9oYb7RBrgw==", "dev": true, - "requires": { - "typescript": "2.6.2" - }, + "license": "MIT", "dependencies": { - "typescript": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.6.2.tgz", - "integrity": "sha1-PFtv1/beCRQmkCfwPAlGdY92c6Q=", - "dev": true - } + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@schematics/package-update": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@schematics/package-update/-/package-update-0.3.2.tgz", - "integrity": "sha512-7aVP4994Hu8vRdTTohXkfGWEwLhrdNP3EZnWyBootm5zshWqlQojUGweZe5zwewsKcixeVOiy2YtW+aI4aGSLA==", + "node_modules/@algolia/recommend": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.46.2.tgz", + "integrity": "sha512-NApbTPj9LxGzNw4dYnZmj2BoXiAc8NmbbH6qBNzQgXklGklt/xldTvu+FACN6ltFsTzoNU6j2mWNlHQTKGC5+Q==", "dev": true, - "requires": { - "rxjs": "5.5.7", - "semver": "5.5.0", - "semver-intersect": "1.3.1" + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@types/jasmine": { - "version": "2.8.6", - "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-2.8.6.tgz", - "integrity": "sha512-clg9raJTY0EOo5pVZKX3ZlMjlYzVU73L71q5OV1jhE2Uezb7oF94jh4CvwrW6wInquQAdhOxJz5VDF2TLUGmmA==", - "dev": true - }, - "@types/jasminewd2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@types/jasminewd2/-/jasminewd2-2.0.3.tgz", - "integrity": "sha512-hYDVmQZT5VA2kigd4H4bv7vl/OhlympwREUemqBdOqtrYTo5Ytm12a5W5/nGgGYdanGVxj0x/VhZ7J3hOg/YKg==", + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.46.2.tgz", + "integrity": "sha512-ekotpCwpSp033DIIrsTpYlGUCF6momkgupRV/FA3m62SreTSZUKjgK6VTNyG7TtYfq9YFm/pnh65bATP/ZWJEg==", "dev": true, - "requires": { - "@types/jasmine": "2.8.6" + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "@types/node": { - "version": "6.0.103", - "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.103.tgz", - "integrity": "sha512-EHU5B9OlENiGEziLiC2XjhjBoVTiX6s4JwZrMHkLQzrzOA0bfZKfcT3fZaalgujcrs2O97VgKaxqguwV+12UJQ==", - "dev": true - }, - "@types/q": { - "version": "0.0.32", - "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz", - "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=", - "dev": true - }, - "@types/selenium-webdriver": { - "version": "2.53.43", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz", - "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==", - "dev": true - }, - "@types/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-FKjsOVbC6B7bdSB5CuzyHCkK69I=", - "dev": true - }, - "@types/strip-json-comments": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/@types/strip-json-comments/-/strip-json-comments-0.0.30.tgz", - "integrity": "sha512-7NQmHra/JILCd1QqpSzl8+mJRc8ZHz3uDm8YV1Ks9IhK0epEiTw8aIErbvH9PI+6XbqhyIQy3462nEsn7UVzjQ==", - "dev": true - }, - "JSONStream": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.2.tgz", - "integrity": "sha1-wQI3G27Dp887hHygDCC7D85Mbeo=", + "node_modules/@algolia/requester-fetch": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.46.2.tgz", + "integrity": "sha512-gKE+ZFi/6y7saTr34wS0SqYFDcjHW4Wminv8PDZEi0/mE99+hSrbKgJWxo2ztb5eqGirQTgIh1AMVacGGWM1iw==", "dev": true, - "requires": { - "jsonparse": "1.3.1", - "through": "2.3.8" + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "accepts": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", - "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", + "node_modules/@algolia/requester-node-http": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.46.2.tgz", + "integrity": "sha512-ciPihkletp7ttweJ8Zt+GukSVLp2ANJHU+9ttiSxsJZThXc4Y2yJ8HGVWesW5jN1zrsZsezN71KrMx/iZsOYpg==", "dev": true, - "requires": { - "mime-types": "2.1.18", - "negotiator": "0.6.1" + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, - "requires": { - "acorn": "4.0.13" - }, + "license": "Apache-2.0", "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" } }, - "acorn-node": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz", - "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", + "node_modules/@angular-devkit/architect": { + "version": "0.2101.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2101.0.tgz", + "integrity": "sha512-vnNAzWXwSRGTHk2K7woIQsj7WDYZp69Z3DBdlxkK0H08ymkJ/ELbhN0/AnIJNNtYCqEb57AH7Ro98n422beDuw==", "dev": true, - "requires": { - "acorn": "5.5.3", - "xtend": "4.0.1" + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.1.0", + "rxjs": "7.8.2" + }, + "bin": { + "architect": "bin/cli.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "addressparser": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz", - "integrity": "sha1-R6++GiqSYhkdtoOOT9HTm0CCF0Y=", + "node_modules/@angular-devkit/core": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-21.1.0.tgz", + "integrity": "sha512-dPfVy0CictDjWffRv4pGTPOFjdlJL3ZkGUqxzaosUjMbJW+Ai9cNn1VNr7zxYZ4kem3BxLBh1thzDsCPrkXlZA==", "dev": true, - "optional": true - }, - "adm-zip": { - "version": "0.4.7", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz", - "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=", - "dev": true + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^5.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true + "node_modules/@angular-devkit/schematics": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-21.1.0.tgz", + "integrity": "sha512-sVgTntCZCOV7mOpHzj6V14KOAoy4B9Ur9yHNRFZVgL2yD77TYRrJ0qwq+l7Im9fSjMCar6csjboqCvyAEpfV1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.1.0", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.21", + "ora": "9.0.0", + "rxjs": "7.8.2" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/animations": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-21.1.0.tgz", + "integrity": "sha512-RTpRdWhwz1PsMJC8NuuYIKCgMFP9EyxOrSaI0bpCLIGtXCfmvvHiU2FkBksV86MqYOf+wurKATb71QcfGrV3Hg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "21.1.0" + } + }, + "node_modules/@angular/build": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-21.1.0.tgz", + "integrity": "sha512-ftms4F/TlkRNhf/4ykFO12zTG0f9sIRZ4fGFnaOVGmnKYkPKZklWvMCPoaoIligHS2pqKye1a5JSiTgTeUDp9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.2101.0", + "@babel/core": "7.28.5", + "@babel/helper-annotate-as-pure": "7.27.3", + "@babel/helper-split-export-declaration": "7.24.7", + "@inquirer/confirm": "5.1.21", + "@vitejs/plugin-basic-ssl": "2.1.0", + "beasties": "0.3.5", + "browserslist": "^4.26.0", + "esbuild": "0.27.2", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "magic-string": "0.30.21", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "8.0.0", + "picomatch": "4.0.3", + "piscina": "5.1.4", + "rolldown": "1.0.0-beta.58", + "sass": "1.97.1", + "semver": "7.7.3", + "source-map-support": "0.5.21", + "tinyglobby": "0.2.15", + "undici": "7.18.0", + "vite": "7.3.0", + "watchpack": "2.5.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.4.4" + }, + "peerDependencies": { + "@angular/compiler": "^21.0.0", + "@angular/compiler-cli": "^21.0.0", + "@angular/core": "^21.0.0", + "@angular/localize": "^21.0.0", + "@angular/platform-browser": "^21.0.0", + "@angular/platform-server": "^21.0.0", + "@angular/service-worker": "^21.0.0", + "@angular/ssr": "^21.1.0", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^21.0.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "tslib": "^2.3.0", + "typescript": ">=5.9 <6.0", + "vitest": "^4.0.8" + }, + "peerDependenciesMeta": { + "@angular/core": { + "optional": true + }, + "@angular/localize": { + "optional": true + }, + "@angular/platform-browser": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + }, + "vitest": { + "optional": true + } + } }, - "agent-base": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", - "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", + "node_modules/@angular/cdk": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/cdk/-/cdk-21.1.0.tgz", + "integrity": "sha512-zvV37HPKhtu0bOfuK0IhjKKq++Xb57Z11uZYZJI34BZnZ5y1TPhJpcmrHhjb2uKUNfDvePUqhlnIlKAXHSBIhw==", "dev": true, - "requires": { - "extend": "3.0.1", - "semver": "5.0.3" - }, + "license": "MIT", "dependencies": { - "semver": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", - "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=", - "dev": true - } + "parse5": "^8.0.0", + "tslib": "^2.3.0" + }, + "peerDependencies": { + "@angular/common": "^21.0.0 || ^22.0.0", + "@angular/core": "^21.0.0 || ^22.0.0", + "@angular/platform-browser": "^21.0.0 || ^22.0.0", + "rxjs": "^6.5.3 || ^7.4.0" } }, - "ajv": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", - "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", + "node_modules/@angular/cli": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-21.1.0.tgz", + "integrity": "sha512-kzk8du388x6EBybJeq5AB27qGm8oGC9HhvBJDbu8o+aBIOY+JwVON9m4SYLCzeT+EVK8sKA1NMVYi2CDerk6hA==", "dev": true, - "requires": { - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1", - "uri-js": "3.0.2" + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2101.0", + "@angular-devkit/core": "21.1.0", + "@angular-devkit/schematics": "21.1.0", + "@inquirer/prompts": "7.10.1", + "@listr2/prompt-adapter-inquirer": "3.0.5", + "@modelcontextprotocol/sdk": "1.25.2", + "@schematics/angular": "21.1.0", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.46.2", + "ini": "6.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.5", + "npm-package-arg": "13.0.2", + "pacote": "21.0.4", + "parse5-html-rewriting-stream": "8.0.0", + "resolve": "1.22.11", + "semver": "7.7.3", + "yargs": "18.0.0", + "zod": "4.3.5" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "ajv-keywords": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.1.0.tgz", - "integrity": "sha1-rCsnk5xUPpXSwG5/f1wnvkqlQ74=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" + "node_modules/@angular/common": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-21.1.0.tgz", + "integrity": "sha512-hL3Chp51TU9iBcIfkNtoBS1wuseP1gsyDW2IFtK5HUpAVhbso9B3fdCaDTFkU98A2unluo2YgzI6D/6IS6N+1g==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/core": "21.1.0", + "rxjs": "^6.5.3 || ^7.4.0" } }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true + "node_modules/@angular/compiler": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-21.1.0.tgz", + "integrity": "sha512-UprCiJwEU1Ilw1dVk+yLgNiHlbH81obAuh92lRKozUQRgtSCpOfCQUM79q5r+VdmCPxDshr79U2Ke0fRaiJfAQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + } }, - "amqplib": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "node_modules/@angular/compiler-cli": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-21.1.0.tgz", + "integrity": "sha512-//BTtxJovsF0LaOWQkOVxWX4EVyNJaPus+IlwWxzmdRHpojIl1Zdyy9BJMVJOifvj3XQ16sZwR1PDWDI5DIWrg==", "dev": true, - "optional": true, - "requires": { - "bitsyntax": "0.0.4", - "bluebird": "3.5.1", - "buffer-more-ints": "0.0.2", - "readable-stream": "1.1.14", - "safe-buffer": "5.1.1" + "license": "MIT", + "dependencies": { + "@babel/core": "7.28.5", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^5.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^18.0.0" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, + "peerDependencies": { + "@angular/compiler": "21.1.0", + "typescript": ">=5.9 <6.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@angular/core": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-21.1.0.tgz", + "integrity": "sha512-QTl9s8GYNN0pt1k3GE6UVlfe6zWtfdykhfchinKq2YJywQ6LBM4UcZgoc56YkgscmyrRFYrr4JYUJjlzTF57+A==", + "license": "MIT", "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true, + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/compiler": "21.1.0", + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0 || ~0.16.0" + }, + "peerDependenciesMeta": { + "@angular/compiler": { "optional": true }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, + "zone.js": { "optional": true } } }, - "ansi-html": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", - "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", - "dev": true + "node_modules/@angular/forms": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-21.1.0.tgz", + "integrity": "sha512-1Qxsu2cQhraKe2dKzIVm7no1qWi76QsXVwY7+VGKRYG7p+fKaFmnr7oU5EbJL66TsFzCb8mDGxLGikS+YE+X/g==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.1.0", + "@angular/core": "21.1.0", + "@angular/platform-browser": "21.1.0", + "rxjs": "^6.5.3 || ^7.4.0" + } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "node_modules/@angular/platform-browser": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-21.1.0.tgz", + "integrity": "sha512-Drkal25x+OuRQosAE/cL4uM5WDmgFehanCpsjQ1jGp6Rxoad6Q5Do1uQAE3qgMKHL1aqCPZ+uWzcVVG+Bn1ddg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/animations": "21.1.0", + "@angular/common": "21.1.0", + "@angular/core": "21.1.0" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/router": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-21.1.0.tgz", + "integrity": "sha512-Sneu0ePuH+bf8ZslRX3iQk1iLziindLskdTeHV1ZCrXdT0ZScsZyI/gjxQKBtsIU9692D2DnFQRLGnzTBYVGVw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "@angular/common": "21.1.0", + "@angular/core": "21.1.0", + "@angular/platform-browser": "21.1.0", + "rxjs": "^6.5.3 || ^7.4.0" + } }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "node_modules/@asamuzakjp/css-color": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-4.1.1.tgz", + "integrity": "sha512-B0Hv6G3gWGMn0xKJ0txEi/jM5iFpT3MfDxmhZFb4W047GvytCf1DHQ1D69W3zHI4yWe2aTZAA0JnbMZ7Xc8DuQ==", "dev": true, - "requires": { - "color-convert": "1.9.1" + "license": "MIT", + "dependencies": { + "@csstools/css-calc": "^2.1.4", + "@csstools/css-color-parser": "^3.1.0", + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4", + "lru-cache": "^11.2.4" } }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "app-root-path": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz", - "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", - "dev": true + "node_modules/@asamuzakjp/dom-selector": { + "version": "6.7.6", + "resolved": "https://registry.npmjs.org/@asamuzakjp/dom-selector/-/dom-selector-6.7.6.tgz", + "integrity": "sha512-hBaJER6A9MpdG3WgdlOolHmbOYvSk46y7IQN/1+iqiCuUu6iWdQrs9DGKF8ocqsEqWujWf/V7b7vaDgiUmIvUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/nwsapi": "^2.3.9", + "bidi-js": "^1.0.3", + "css-tree": "^3.1.0", + "is-potential-custom-element-name": "^1.0.1", + "lru-cache": "^11.2.4" + } }, - "append-transform": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", - "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "node_modules/@asamuzakjp/dom-selector/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "requires": { - "default-require-extensions": "1.0.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true + "node_modules/@asamuzakjp/nwsapi": { + "version": "2.3.9", + "resolved": "https://registry.npmjs.org/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz", + "integrity": "sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==", + "dev": true, + "license": "MIT" }, - "are-we-there-yet": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", - "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", + "node_modules/@babel/code-frame": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.28.6.tgz", + "integrity": "sha512-JYgintcMjRiCvS8mMECzaEn+m3PfoQiyqukOMCCVQtoJGYJw8j/8LBJEiqkHLkfwCcs74E3pbAUFNg7d9VNJ+Q==", "dev": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.5" + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.28.5", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "node_modules/@babel/compat-data": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.6.tgz", + "integrity": "sha512-2lfu57JtzctfIrcGMz992hyLlByuzgIk58+hhGCxjKZ3rWI82NnVLjXcaTqkI2NvlcvOskZaiZ5kjUALo3Lpxg==", "dev": true, - "requires": { - "sprintf-js": "1.0.3" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, - "requires": { - "arr-flatten": "1.1.0" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-filter": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", - "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-flatten": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz", - "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=", - "dev": true + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" }, - "array-includes": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "requires": { - "define-properties": "1.1.2", - "es-abstract": "1.11.0" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "array-map": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", - "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", - "dev": true - }, - "array-reduce": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", - "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", - "dev": true - }, - "array-slice": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-0.2.3.tgz", - "integrity": "sha1-3Tz7gO15c6dRF82sabC5nshhhvU=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "node_modules/@babel/generator": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.6.tgz", + "integrity": "sha512-lOoVRwADj8hjf7al89tvQ2a1lf53Z+7tiXMgpZJL3maQPDxh0DgLMN62B2MKUOFcoodBHLMbDM6WAbKgNy5Suw==", "dev": true, - "requires": { - "array-uniq": "1.0.3" + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" } }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", "dev": true, - "optional": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "node_modules/@babel/helper-compilation-targets": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", + "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", "dev": true, - "requires": { - "bn.js": "4.11.8", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.28.6", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" } }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, - "requires": { - "util": "0.10.3" + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "ast-types": { - "version": "0.11.3", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", - "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", "dev": true, - "optional": true + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } }, - "astw": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", - "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", + "node_modules/@babel/helper-module-imports": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz", + "integrity": "sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==", "dev": true, - "requires": { - "acorn": "4.0.13" - }, + "license": "MIT", "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } + "@babel/traverse": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "async": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", + "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", "dev": true, - "requires": { - "lodash": "4.17.5" + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.28.6", + "@babel/helper-validator-identifier": "^7.28.5", + "@babel/traverse": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "async-foreach": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, - "optional": true - }, - "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "atob": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.0.3.tgz", - "integrity": "sha1-GcenYEc3dEaPILLS0DNyrX1Mv10=", - "dev": true - }, - "autoprefixer": { - "version": "7.2.6", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", - "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", - "dev": true, - "requires": { - "browserslist": "2.11.3", - "caniuse-lite": "1.0.30000820", - "normalize-range": "0.1.2", - "num2fraction": "1.2.2", - "postcss": "6.0.21", - "postcss-value-parser": "3.3.0" - } - }, - "awesome-phonenumber": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/awesome-phonenumber/-/awesome-phonenumber-2.2.5.tgz", - "integrity": "sha512-CHVEWEtXhaUB4ZGki/MQOlxK9wX+x3rw0/OARxB/srJTBP7b8nZjuE69WKQIUmciYdYGP2qywFPyubewJnFLbQ==" - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "axios": { - "version": "0.15.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.15.3.tgz", - "integrity": "sha1-LJ1jiy4ZGgjqHWzJiOrda6W9wFM=", - "dev": true, - "optional": true, - "requires": { - "follow-redirects": "1.0.0" - } - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "dev": true, - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.5", - "source-map": "0.5.7", - "trim-right": "1.0.1" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "dev": true, - "requires": { - "core-js": "2.5.3", - "regenerator-runtime": "0.11.1" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", + "node_modules/@babel/helpers": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.6.tgz", + "integrity": "sha512-xOBvwq86HHdB7WUDTfKfT/Vuxh7gElQ+Sfti2Cy6yIWNW05P8iUslOVcZ4/sKbE+/jQaukQAdz/gf3724kYdqw==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "lodash": "4.17.5" + "license": "MIT", + "dependencies": { + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", + "node_modules/@babel/parser": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.6.tgz", + "integrity": "sha512-TeR9zWR18BvbfPmGbLampPMW+uW1NZnJlRuuHso8i87QZNq2JRF9i6RgxRqtEq+wQGsS19NNTWr2duhnE49mfQ==", "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "debug": "2.6.9", - "globals": "9.18.0", - "invariant": "2.2.4", - "lodash": "4.17.5" + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.6" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" } }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", + "node_modules/@babel/template": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.28.6.tgz", + "integrity": "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==", "dev": true, - "requires": { - "babel-runtime": "6.26.0", - "esutils": "2.0.2", - "lodash": "4.17.5", - "to-fast-properties": "1.0.3" + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/parser": "^7.28.6", + "@babel/types": "^7.28.6" + }, + "engines": { + "node": ">=6.9.0" } }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", - "dev": true + "node_modules/@babel/traverse": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.6.tgz", + "integrity": "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.28.6", + "@babel/generator": "^7.28.6", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.6", + "@babel/template": "^7.28.6", + "@babel/types": "^7.28.6", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true + "node_modules/@babel/types": { + "version": "7.28.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.6.tgz", + "integrity": "sha512-0ZrskXVEHSWIqZM/sQZ4EV3jZJXRkio/WCxaqKZP1g//CEWEPSfeZFcms4XeKBCHU0ZKnIkdJeU/kF+eRp5lBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "1.0.1", - "class-utils": "0.3.6", - "component-emitter": "1.2.1", - "define-property": "1.0.0", - "isobject": "3.0.1", - "mixin-deep": "1.3.1", - "pascalcase": "0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } + "node_modules/@csstools/color-helpers": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.1.0.tgz", + "integrity": "sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" } }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.3.tgz", - "integrity": "sha512-MsAhsUW1GxCdgYSO6tAfZrNapmUKk7mWx/k5mFY/A1gBtkaCaNapTg+FExCw1r9yeaZhqx/xPg43xgTFH6KL5w==", - "dev": true - }, - "base64id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", - "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "node_modules/@csstools/css-calc": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.4.tgz", + "integrity": "sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ==", "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", + "node_modules/@csstools/css-color-parser": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz", + "integrity": "sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA==", "dev": true, - "requires": { - "callsite": "1.0.0" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/color-helpers": "^5.1.0", + "@csstools/css-calc": "^2.1.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^3.0.5", + "@csstools/css-tokenizer": "^3.0.4" } }, - "big.js": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", - "dev": true - }, - "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", - "dev": true - }, - "bitsyntax": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/bitsyntax/-/bitsyntax-0.0.4.tgz", - "integrity": "sha1-6xDMb4K4xJDj6FaY8H6D1G4MuoI=", + "node_modules/@csstools/css-parser-algorithms": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz", + "integrity": "sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ==", "dev": true, - "optional": true, - "requires": { - "buffer-more-ints": "0.0.2" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@csstools/css-tokenizer": "^3.0.4" } }, - "bl": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.1.2.tgz", - "integrity": "sha1-/cqHGplxOqANGeO7ukHER4emU5g=", + "node_modules/@csstools/css-syntax-patches-for-csstree": { + "version": "1.0.25", + "resolved": "https://registry.npmjs.org/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.25.tgz", + "integrity": "sha512-g0Kw9W3vjx5BEBAF8c5Fm2NcB/Fs8jJXh85aXqwEXiL+tqtOut07TWgyaGzAAfTM+gKckrrncyeGEZPcaRgm2Q==", "dev": true, - "optional": true, - "requires": { - "readable-stream": "2.0.6" - }, - "dependencies": { - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" } + ], + "license": "MIT-0", + "engines": { + "node": ">=18" } }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", - "dev": true - }, - "block-stream": { - "version": "0.0.9", - "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", - "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "node_modules/@csstools/css-tokenizer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz", + "integrity": "sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw==", "dev": true, - "optional": true, - "requires": { - "inherits": "2.0.3" + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": ">=18" } }, - "blocking-proxy": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-0.0.5.tgz", - "integrity": "sha1-RikF4Nz76pcPQao3Ij3anAexkSs=", + "node_modules/@emnapi/core": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.8.1.tgz", + "integrity": "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg==", "dev": true, - "requires": { - "minimist": "1.2.0" - }, + "license": "MIT", + "optional": true, "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" } }, - "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "1.0.4", - "debug": "2.6.9", - "depd": "1.1.2", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "on-finished": "2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "1.6.16" - }, - "dependencies": { - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true - } - } - }, - "bonjour": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", - "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "node_modules/@emnapi/runtime": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.8.1.tgz", + "integrity": "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg==", "dev": true, - "requires": { - "array-flatten": "2.1.1", - "deep-equal": "1.0.1", - "dns-equal": "1.0.0", - "dns-txt": "2.0.2", - "multicast-dns": "6.2.3", - "multicast-dns-service-types": "1.1.0" + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", "dev": true, - "requires": { - "hoek": "2.16.3" + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" } }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", + "cpu": [ + "ppc64" + ], "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" } }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", + "node_modules/@esbuild/android-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", + "cpu": [ + "arm" + ], "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-pack": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", - "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.8.0", - "defined": "1.0.0", - "safe-buffer": "5.1.1", - "through2": "2.0.3", - "umd": "3.0.3" - } - }, - "browser-resolve": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", - "dev": true, - "requires": { - "resolve": "1.1.7" - }, - "dependencies": { - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "browserify": { - "version": "14.5.0", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-14.5.0.tgz", - "integrity": "sha512-gKfOsNQv/toWz+60nSPfYzuwSEdzvV2WdxrVPUbPD/qui44rAkB3t3muNtmmGYHqrG56FGwX9SUEQmzNLAeS7g==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "assert": "1.4.1", - "browser-pack": "6.0.4", - "browser-resolve": "1.11.2", - "browserify-zlib": "0.2.0", - "buffer": "5.1.0", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "defined": "1.0.0", - "deps-sort": "2.0.0", - "domain-browser": "1.1.7", - "duplexer2": "0.1.4", - "events": "1.1.1", - "glob": "7.1.2", - "has": "1.0.1", - "htmlescape": "1.1.1", - "https-browserify": "1.0.0", - "inherits": "2.0.3", - "insert-module-globals": "7.0.4", - "labeled-stream-splicer": "2.0.1", - "module-deps": "4.1.1", - "os-browserify": "0.3.0", - "parents": "1.0.1", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "read-only-stream": "2.0.0", - "readable-stream": "2.3.5", - "resolve": "1.6.0", - "shasum": "1.0.2", - "shell-quote": "1.6.1", - "stream-browserify": "2.0.1", - "stream-http": "2.8.1", - "string_decoder": "1.0.3", - "subarg": "1.0.0", - "syntax-error": "1.4.0", - "through2": "2.0.3", - "timers-browserify": "1.4.2", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4", - "xtend": "4.0.1" - }, - "dependencies": { - "buffer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", - "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", - "dev": true, - "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.11" - } - }, - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "domain-browser": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", - "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "timers-browserify": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", - "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", - "dev": true, - "requires": { - "process": "0.11.10" - } - } + "node_modules/@esbuild/android-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "browserify-aes": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.1.tgz", - "integrity": "sha512-UGnTYAnB2a3YuYKIRy1/4FB2HdM866E0qC46JXvVTYKlBlZlnvfpSfY6OKfXZAkv70eJ2a1SqzpAo5CRhZGDFg==", + "node_modules/@esbuild/android-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" } }, - "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "browserify-aes": "1.1.1", - "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.3" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" } }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "bn.js": "4.11.8", - "randombytes": "2.0.6" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.0" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" } }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "node_modules/@esbuild/linux-arm": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", + "cpu": [ + "arm" + ], "dev": true, - "requires": { - "pako": "1.0.6" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "browserslist": { - "version": "2.11.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz", - "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==", + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "caniuse-lite": "1.0.30000820", - "electron-to-chromium": "1.3.40" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", + "cpu": [ + "ia32" + ], "dev": true, - "requires": { - "base64-js": "1.2.3", - "ieee754": "1.1.11", - "isarray": "1.0.0" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "buffer-from": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", - "dev": true - }, - "buffer-indexof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", - "dev": true - }, - "buffer-more-ints": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/buffer-more-ints/-/buffer-more-ints-0.0.2.tgz", - "integrity": "sha1-JrOIXRD6E9t/wBquOquHAZngEkw=", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "buildmail": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/buildmail/-/buildmail-4.0.1.tgz", - "integrity": "sha1-h393OLeHKYccmhBeO4N9K+EaenI=", + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", + "cpu": [ + "loong64" + ], "dev": true, + "license": "MIT", "optional": true, - "requires": { - "addressparser": "1.0.1", - "libbase64": "0.1.0", - "libmime": "3.0.0", - "libqp": "1.1.0", - "nodemailer-fetch": "1.6.0", - "nodemailer-shared": "1.1.0", - "punycode": "1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true, - "optional": true - } + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "10.0.4", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", - "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "chownr": "1.0.1", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "lru-cache": "4.1.2", - "mississippi": "2.0.0", - "mkdirp": "0.5.1", - "move-concurrently": "1.0.1", - "promise-inflight": "1.0.1", - "rimraf": "2.6.2", - "ssri": "5.3.0", - "unique-filename": "1.1.0", - "y18n": "4.0.0" - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "1.0.0", - "component-emitter": "1.2.1", - "get-value": "2.0.6", - "has-value": "1.0.0", - "isobject": "3.0.1", - "set-value": "2.0.0", - "to-object-path": "0.3.0", - "union-value": "1.0.0", - "unset-value": "1.0.0" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "cache-loader": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cache-loader/-/cache-loader-1.2.2.tgz", - "integrity": "sha512-rsGh4SIYyB9glU+d0OcHwiXHXBoUgDhHZaQ1KAbiXqfz1CDPxtTboh1gPbJ0q2qdO8a9lfcjgC5CJ2Ms32y5bw==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", + "cpu": [ + "ppc64" + ], "dev": true, - "requires": { - "loader-utils": "1.1.0", - "mkdirp": "0.5.1", - "neo-async": "2.5.0", - "schema-utils": "0.4.5" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "cached-path-relative": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", - "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", - "dev": true - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", + "cpu": [ + "riscv64" + ], "dev": true, - "requires": { - "no-case": "2.3.2", - "upper-case": "1.1.3" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", + "cpu": [ + "s390x" + ], "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "caniuse-lite": { - "version": "1.0.30000820", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000820.tgz", - "integrity": "sha512-E0dpVjnt1XTNmWlGgdiae/tOF0jrJ/s+dOnwk8PLmPdu5uSu8wTLJhhbhcgUWU4aO9Iy5yUMZYxT60JS259sbQ==", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", + "node_modules/@esbuild/linux-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "chalk": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.2.2.tgz", - "integrity": "sha512-LvixLAQ4MYhbf7hgL4o5PeK32gJKvVzDRiSNIApDofQvyhl8adgG2lJVXn4+ekQoK7HL9RF8lqxwerpe0x2pCw==", + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "4.5.0" + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.3", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" - } - }, - "chownr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", - "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - }, - "circular-dependency-plugin": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/circular-dependency-plugin/-/circular-dependency-plugin-4.4.0.tgz", - "integrity": "sha512-yEFtUNUYT4jBykEX5ZOHw+5goA3glGZr9wAXIQqoyakjz5H5TeUmScnWRc52douAhb9eYzK3s7V6bXfNnjFdzg==", - "dev": true - }, - "circular-json": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.1.tgz", - "integrity": "sha512-UjgcRlTAhAkLeXmDe2wK7ktwy/tgAqxiSndTIPiFZuIPLZmzHzWMwUIe9h9m/OokypG7snxCDEuwJshGBdPvaw==", - "dev": true - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "define-property": "0.2.5", - "isobject": "3.0.1", - "static-extend": "0.1.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" } }, - "clean-css": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.1.11.tgz", - "integrity": "sha1-Ls3xRaujj1R0DybO/Q/z4D4SXWo=", + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "source-map": "0.5.7" + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" } }, - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - }, - "clone-deep": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-2.0.2.tgz", - "integrity": "sha512-SZegPTKjCgpQH63E+eN6mVEEPdQBOUzjyJm5Pora4lrwWRFS8I0QAxV/KD6vV/i0WuijHZWQC1fMsPEdxfdVCQ==", - "dev": true, - "requires": { - "for-own": "1.0.0", - "is-plain-object": "2.0.4", - "kind-of": "6.0.2", - "shallow-clone": "1.0.0" - }, - "dependencies": { - "for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" } }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "codelyzer": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/codelyzer/-/codelyzer-4.2.1.tgz", - "integrity": "sha512-CKwfgpfkqi9dyzy4s6ELaxJ54QgJ6A8iTSsM4bzHbLuTpbKncvNc3DUlCvpnkHBhK47gEf4qFsWoYqLrJPhy6g==", + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "app-root-path": "2.0.1", - "css-selector-tokenizer": "0.7.0", - "cssauron": "1.4.0", - "semver-dsl": "1.0.1", - "source-map": "0.5.7", - "sprintf-js": "1.0.3" + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" } }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "map-visit": "1.0.0", - "object-visit": "1.0.1" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "color-convert": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", + "cpu": [ + "ia32" + ], "dev": true, - "requires": { - "color-name": "1.1.3" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - }, - "combine-lists": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/combine-lists/-/combine-lists-1.0.1.tgz", - "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", + "node_modules/@esbuild/win32-x64": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "lodash": "4.17.5" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" } }, - "combine-source-map": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", - "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "node_modules/@exodus/bytes": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@exodus/bytes/-/bytes-1.9.0.tgz", + "integrity": "sha512-lagqsvnk09NKogQaN/XrtlWeUF8SRhT12odMvbTIIaVObqzwAogL6jhR4DAp0gPuKoM1AOVrKUshJpRdpMFrww==", "dev": true, - "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" + "license": "MIT", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" }, - "dependencies": { - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true + "peerDependencies": { + "@noble/hashes": "^1.8.0 || ^2.0.0" + }, + "peerDependenciesMeta": { + "@noble/hashes": { + "optional": true } } }, - "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "node_modules/@hono/node-server": { + "version": "1.19.9", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.9.tgz", + "integrity": "sha512-vHL6w3ecZsky+8P5MD+eFfaGTyCeOHUIFYMGpQGbrBTSmNNoxv0if69rEZ5giu36weC5saFuznL411gRX7bJDw==", "dev": true, - "requires": { - "delayed-stream": "1.0.0" + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" } }, - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "common-tags": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.7.2.tgz", - "integrity": "sha512-joj9ZlUOjCrwdbmiLqafeUSgkUM74NqhLsZtSqDmhKudaIY197zTrb8JMl31fMnCUuxwFT23eC/oWvrZzDLRJQ==", + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "dev": true, - "requires": { - "babel-runtime": "6.26.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "compare-versions": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.1.0.tgz", - "integrity": "sha512-4hAxDSBypT/yp2ySFD346So6Ragw5xmBn/e/agIGl3bZr6DLUqnoRZPusxKrXdYRZpgexO9daejmIenlq/wrIQ==", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "compressible": { - "version": "2.0.13", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz", - "integrity": "sha1-DRAgq5JLL9tNYnmHXH1tq6a6p6k=", - "dev": true, - "requires": { - "mime-db": "1.33.0" - } - }, - "compression": { - "version": "1.7.2", - "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz", - "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=", - "dev": true, - "requires": { - "accepts": "1.3.5", - "bytes": "3.0.0", - "compressible": "2.0.13", - "debug": "2.6.9", - "on-headers": "1.0.1", - "safe-buffer": "5.1.1", - "vary": "1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "1.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "typedarray": "0.0.6" - } - }, - "connect": { - "version": "3.6.6", - "resolved": "https://registry.npmjs.org/connect/-/connect-3.6.6.tgz", - "integrity": "sha1-Ce/2xVr3I24TcTWnJXSFi2eG9SQ=", - "dev": true, - "requires": { - "debug": "2.6.9", - "finalhandler": "1.1.0", - "parseurl": "1.3.2", - "utils-merge": "1.0.1" - }, - "dependencies": { - "finalhandler": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz", - "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.3.1", - "unpipe": "1.0.0" - } - }, - "statuses": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz", - "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=", - "dev": true + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "connect-history-api-fallback": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz", - "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=", - "dev": true - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "dev": true, - "requires": { - "date-now": "0.1.4" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", - "dev": true - }, - "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true - }, - "cookie": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz", - "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dev": true, - "requires": { - "aproba": "1.2.0", - "fs-write-stream-atomic": "1.0.10", - "iferr": "0.1.5", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "copy-webpack-plugin": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-4.4.3.tgz", - "integrity": "sha512-v4THQ24Tks2NkyOvZuFDgZVfDD9YaA9rwYLZTrWg2GHIA8lrH5DboEyeoorh5Skki+PUbgSmnsCwhMWqYrQZrA==", - "dev": true, - "requires": { - "cacache": "10.0.4", - "find-cache-dir": "1.0.0", - "globby": "7.1.1", - "is-glob": "4.0.0", - "loader-utils": "1.1.0", - "minimatch": "3.0.4", - "p-limit": "1.2.0", - "serialize-javascript": "1.4.0" - }, - "dependencies": { - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "core-js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", - "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=" - }, - "core-object": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/core-object/-/core-object-3.1.5.tgz", - "integrity": "sha512-sA2/4+/PZ/KV6CKgjrVrrUVBKCkdDO02CUlQ0YKTQoYUwPYNOtOAcWlbYhd5v/1JqYaA6oZ4sDlOU4ppVw6Wbg==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, - "requires": { - "chalk": "2.2.2" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-2.2.2.tgz", - "integrity": "sha512-GiNXLwAFPYHy25XmTPpafYvn3CLAkJ8FLsscq78MQd1Kh0OU6Yzhn4eV2MVF4G9WEQZoWEGltatdR+ntGPMl5A==", - "dev": true, - "requires": { - "is-directory": "0.3.1", - "js-yaml": "3.11.0", - "minimist": "1.2.0", - "object-assign": "4.1.1", - "os-homedir": "1.0.2", - "parse-json": "2.2.0", - "require-from-string": "1.2.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true } } }, - "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dev": true, - "requires": { - "bn.js": "4.11.8", - "elliptic": "6.4.0" + "license": "MIT", + "dependencies": { + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, - "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.11" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, - "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.11" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "cross-spawn": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", - "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, - "optional": true, - "requires": { - "lru-cache": "4.1.2", - "which": "1.3.0" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dev": true, - "requires": { - "boom": "2.10.1" + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "node_modules/@inquirer/prompts": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "dev": true, - "requires": { - "browserify-cipher": "1.0.0", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", - "inherits": "2.0.3", - "pbkdf2": "3.0.14", - "public-encrypt": "4.0.0", - "randombytes": "2.0.6", - "randomfill": "1.0.4" + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "css-parse": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-1.7.0.tgz", - "integrity": "sha1-Mh9s9zeCpv91ERE5D8BeLGV9jJs=", - "dev": true - }, - "css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dev": true, - "requires": { - "boolbase": "1.0.0", - "css-what": "2.1.0", - "domutils": "1.5.1", - "nth-check": "1.0.1" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "css-selector-tokenizer": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", - "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dev": true, - "requires": { - "cssesc": "0.1.0", - "fastparse": "1.1.1", - "regexpu-core": "1.0.0" + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "css-what": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz", - "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", - "dev": true - }, - "cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, - "requires": { - "through": "2.3.8" + "license": "MIT", + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "cssesc": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", - "dev": true - }, - "cuint": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cuint/-/cuint-0.2.2.tgz", - "integrity": "sha1-QICG1AlVDCYxFVYZ6fp7ytw7mRs=", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, - "requires": { - "array-find-index": "1.0.2" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "custom-event": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", - "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", - "dev": true - }, - "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", - "dev": true - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, - "requires": { - "es5-ext": "0.10.41" + "license": "MIT", + "engines": { + "node": "20 || >=22" } }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, + "license": "MIT", "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } + "@isaacs/balanced-match": "^4.0.1" + }, + "engines": { + "node": "20 || >=22" } }, - "data-uri-to-buffer": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", "dev": true, - "optional": true - }, - "date-format": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/date-format/-/date-format-1.2.0.tgz", - "integrity": "sha1-YV6CjiM90aubua4JUODOzPpuytg=", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, - "requires": { - "ms": "2.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "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==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } }, - "default-require-extensions": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", - "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", "dev": true, - "requires": { - "strip-bom": "2.0.0" + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "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==", "dev": true, - "requires": { - "foreach": "2.0.5", - "object-keys": "1.0.11" + "license": "MIT", + "engines": { + "node": ">=6.0.0" } }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "dev": true, - "requires": { - "is-descriptor": "1.0.2", - "isobject": "3.0.1" - }, + "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==", + "dev": true, + "license": "MIT", "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "defined": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", - "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", - "dev": true + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.5.tgz", + "integrity": "sha512-WELs+hj6xcilkloBXYf9XXK8tYEnKsgLj01Xl5ONUJpKjmT5hGVUzNUS5tooUxs7pGMrw+jFD/41WpqW4V3LDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^3.0.8" + }, + "engines": { + "node": ">=20.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.5" + } }, - "degenerator": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz", - "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=", + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.4.4.tgz", + "integrity": "sha512-XaKL705gDWd6XVls3ATDj13ZdML/LqSIxwgnYpG8xTzH2ifArx8fMMDdvqGE/Emd+W6R90W2fveZcJ0AyS8Y0w==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", "optional": true, - "requires": { - "ast-types": "0.11.3", - "escodegen": "1.9.1", - "esprima": "3.1.3" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.4.4.tgz", + "integrity": "sha512-GPHGEVcwJlkD01GmIr7B4kvbIcUDS2+kBadVEd7lU4can1RZaZQLDDBJRrrNfS2Kavvl0VLI/cMv7UASAXGrww==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.4.4.tgz", + "integrity": "sha512-cmev5/dZr5ACKri9f6GU6lZCXTjMhV72xujlbOhFCgFXrt4W0TxGsmY8kA1BITvH60JBKE50cSxsiulybAbrrw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.4.4.tgz", + "integrity": "sha512-mALqr7DE42HsiwVTKpQWxacjHoJk+e9p00RWIJqTACh/hpucxp/0lK/XMh5XzWnU/TDCZLukq1+vNqnNumTP/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.4.4.tgz", + "integrity": "sha512-QjLs8OcmCNcraAcLoZyFlo0atzBJniQLLwhtR+ymQqS5kLYpV5RqwriL87BW+ZiR9ZiGgZx3evrz5vnWPtJ1fQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-arm64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-arm64/-/lmdb-win32-arm64-3.4.4.tgz", + "integrity": "sha512-tr/pwHDlZ33forLGAr0tI04cRmP4SgF93yHbb+2zvZiDEyln5yMHhbKDySxY66aUOkhvBvTuHq9q/3YmTj6ZHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.4.4.tgz", + "integrity": "sha512-KRzfocJzB/mgoTCqnMawuLSKheHRVTqWfSmouIgYpFs6Hx4zvZSvsZKSCEb5gHmICy7qsx9l06jk3MFTtiFVAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.2.tgz", + "integrity": "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==", + "dev": true, + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.7", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { "optional": true + }, + "zod": { + "optional": false } } }, - "del": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", - "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", - "dev": true, - "requires": { - "globby": "6.1.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "p-map": "1.2.0", - "pify": "3.0.0", - "rimraf": "2.6.2" - }, - "dependencies": { - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - } - } + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "denodeify": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/denodeify/-/denodeify-1.2.1.tgz", - "integrity": "sha1-OjYof1A05pnnV3kBBSwubJQlFjE=", - "dev": true + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] }, - "deps-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", - "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "JSONStream": "1.3.2", - "shasum": "1.0.2", - "subarg": "1.0.0", - "through2": "2.0.3" - } + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "node_modules/@napi-rs/nice": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.1.1.tgz", + "integrity": "sha512-xJIPs+bYuc9ASBl+cvGsKbGrJmS6fAKaSZCnT0lhahT5rhA2VVy9/EcIgd2JhtEuFOJNx7UHNn/qiTPTY4nrQw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.1.1", + "@napi-rs/nice-android-arm64": "1.1.1", + "@napi-rs/nice-darwin-arm64": "1.1.1", + "@napi-rs/nice-darwin-x64": "1.1.1", + "@napi-rs/nice-freebsd-x64": "1.1.1", + "@napi-rs/nice-linux-arm-gnueabihf": "1.1.1", + "@napi-rs/nice-linux-arm64-gnu": "1.1.1", + "@napi-rs/nice-linux-arm64-musl": "1.1.1", + "@napi-rs/nice-linux-ppc64-gnu": "1.1.1", + "@napi-rs/nice-linux-riscv64-gnu": "1.1.1", + "@napi-rs/nice-linux-s390x-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-gnu": "1.1.1", + "@napi-rs/nice-linux-x64-musl": "1.1.1", + "@napi-rs/nice-openharmony-arm64": "1.1.1", + "@napi-rs/nice-win32-arm64-msvc": "1.1.1", + "@napi-rs/nice-win32-ia32-msvc": "1.1.1", + "@napi-rs/nice-win32-x64-msvc": "1.1.1" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.1.1.tgz", + "integrity": "sha512-kjirL3N6TnRPv5iuHw36wnucNqXAO46dzK9oPb0wj076R5Xm8PfUVA9nAFB5ZNMmfJQJVKACAPd/Z2KYMppthw==", + "cpu": [ + "arm" + ], "dev": true, - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" } }, - "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.1.1.tgz", + "integrity": "sha512-blG0i7dXgbInN5urONoUCNf+DUEAavRffrO7fZSeoRMJc5qD+BJeNcpr54msPF6qfDD6kzs9AQJogZvT2KD5nw==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "repeating": "2.0.1" + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" } }, - "detect-node": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz", - "integrity": "sha1-ogM8CcyOFY03dI+951B4Mr1s4Sc=", - "dev": true - }, - "detective": { - "version": "4.7.1", - "resolved": "https://registry.npmjs.org/detective/-/detective-4.7.1.tgz", - "integrity": "sha512-H6PmeeUcZloWtdt4DAkFyzFL94arpHr3NOwwmVILFiy+9Qd4JTxxXrzfyGk/lmct2qVGBwTSwSXagqu2BxmWig==", + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.1.1.tgz", + "integrity": "sha512-s/E7w45NaLqTGuOjC2p96pct4jRfo61xb9bU1unM/MJ/RFkKlJyJDx7OJI/O0ll/hrfpqKopuAFDV8yo0hfT7A==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "acorn": "5.5.3", - "defined": "1.0.0" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" } }, - "di": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", - "integrity": "sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=", - "dev": true - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.1.1.tgz", + "integrity": "sha512-dGoEBnVpsdcC+oHHmW1LRK5eiyzLwdgNQq3BmZIav+9/5WTZwBYX7r5ZkQC07Nxd3KHOCkgbHSh4wPkH1N1LiQ==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "bn.js": "4.11.8", - "miller-rabin": "4.0.1", - "randombytes": "2.0.6" + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" } }, - "dir-glob": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", - "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.1.1.tgz", + "integrity": "sha512-kHv4kEHAylMYmlNwcQcDtXjklYp4FCf0b05E+0h6nDHsZ+F0bDe04U/tXNOqrx5CmIAth4vwfkjjUmp4c4JktQ==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "arrify": "1.0.1", - "path-type": "3.0.0" + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" } }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.1.1.tgz", + "integrity": "sha512-E1t7K0efyKXZDoZg1LzCOLxgolxV58HCkaEkEvIYQx12ht2pa8hoBo+4OB3qh7e+QiBlp1SRf+voWUZFxyhyqg==", + "cpu": [ + "arm" + ], "dev": true, - "requires": { - "ip": "1.1.5", - "safe-buffer": "5.1.1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "dns-txt": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", - "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.1.1.tgz", + "integrity": "sha512-CIKLA12DTIZlmTaaKhQP88R3Xao+gyJxNWEn04wZwC2wmRapNnxCUZkVwggInMJvtVElA+D4ZzOU5sX4jV+SmQ==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "buffer-indexof": "1.1.1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "dom-converter": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.1.4.tgz", - "integrity": "sha1-pF71cnuJDJv/5tfIduexnLDhfzs=", + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.1.1.tgz", + "integrity": "sha512-+2Rzdb3nTIYZ0YJF43qf2twhqOCkiSrHx2Pg6DJaCPYhhaxbLcdlV8hCRMHghQ+EtZQWGNcS2xF4KxBhSGeutg==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "utila": "0.3.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "dom-serialize": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", - "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.1.1.tgz", + "integrity": "sha512-4FS8oc0GeHpwvv4tKciKkw3Y4jKsL7FRhaOeiPei0X9T4Jd619wHNe4xCLmN2EMgZoeGg+Q7GY7BsvwKpL22Tg==", + "cpu": [ + "ppc64" + ], "dev": true, - "requires": { - "custom-event": "1.0.1", - "ent": "2.2.0", - "extend": "3.0.1", - "void-elements": "2.0.1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "dom-serializer": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", - "integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=", + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.1.1.tgz", + "integrity": "sha512-HU0nw9uD4FO/oGCCk409tCi5IzIZpH2agE6nN4fqpwVlCn5BOq0MS1dXGjXaG17JaAvrlpV5ZeyZwSon10XOXw==", + "cpu": [ + "riscv64" + ], "dev": true, - "requires": { - "domelementtype": "1.1.3", - "entities": "1.1.1" - }, - "dependencies": { - "domelementtype": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", - "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", - "dev": true - } + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "domelementtype": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz", - "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=", - "dev": true - }, - "domhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.1.0.tgz", - "integrity": "sha1-0mRvXlf2w7qxHPbLBdPArPdBJZQ=", + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.1.1.tgz", + "integrity": "sha512-2YqKJWWl24EwrX0DzCQgPLKQBxYDdBxOHot1KWEq7aY2uYeX+Uvtv4I8xFVVygJDgf6/92h9N3Y43WPx8+PAgQ==", + "cpu": [ + "s390x" + ], "dev": true, - "requires": { - "domelementtype": "1.3.0" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.1.1.tgz", + "integrity": "sha512-/gaNz3R92t+dcrfCw/96pDopcmec7oCcAQ3l/M+Zxr82KT4DljD37CpgrnXV+pJC263JkW572pdbP3hP+KjcIg==", + "cpu": [ + "x64" + ], "dev": true, - "requires": { - "dom-serializer": "0.1.0", - "domelementtype": "1.3.0" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" } }, - "double-ended-queue": { - "version": "2.1.0-0", - "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz", - "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw=", + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.1.1.tgz", + "integrity": "sha512-xScCGnyj/oppsNPMnevsBe3pvNaoK7FGvMjT35riz9YdhB2WtTG47ZlbxtOLpjeO9SqqQ2J2igCmz6IJOD5JYw==", + "cpu": [ + "x64" + ], "dev": true, - "optional": true + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "node_modules/@napi-rs/nice-openharmony-arm64": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-openharmony-arm64/-/nice-openharmony-arm64-1.1.1.tgz", + "integrity": "sha512-6uJPRVwVCLDeoOaNyeiW0gp2kFIM4r7PL2MczdZQHkFi9gVlgm+Vn+V6nTWRcu856mJ2WjYJiumEajfSm7arPQ==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "readable-stream": "2.3.5" + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">= 10" } }, - "duplexify": { - "version": "3.5.4", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.4.tgz", - "integrity": "sha512-JzYSLYMhoVVBe8+mbHQ4KgpvHpm0DZpJuL8PY93Vyv1fW7jYJ90LoXa1di/CVbJM+TgMs91rbDapE/RNIfnJsA==", + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.1.1.tgz", + "integrity": "sha512-uoTb4eAvM5B2aj/z8j+Nv8OttPf2m+HVx3UjA5jcFxASvNhQriyCQF1OB1lHL43ZhW+VwZlgvjmP5qF3+59atA==", + "cpu": [ + "arm64" + ], "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "stream-shift": "1.0.0" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" } }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.1.1.tgz", + "integrity": "sha512-CNQqlQT9MwuCsg1Vd/oKXiuH+TcsSPJmlAFc5frFyX/KkOh0UpBLEj7aoY656d5UKZQMQFP7vJNa1DNUNORvug==", + "cpu": [ + "ia32" + ], "dev": true, + "license": "MIT", "optional": true, - "requires": { - "jsbn": "0.1.1" + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" } }, - "ee-first": { + "node_modules/@napi-rs/nice-win32-x64-msvc": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "2.5.7", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz", - "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=", - "dev": true - }, - "electron-to-chromium": { - "version": "1.3.40", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.40.tgz", - "integrity": "sha1-H71tl779crim+SHcONIkE9L2/d8=", - "dev": true - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true, - "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "ember-cli-string-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ember-cli-string-utils/-/ember-cli-string-utils-1.1.0.tgz", - "integrity": "sha1-ObZ3/CgF9VFzc1N2/O8njqpEUqE=", - "dev": true + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.1.1.tgz", + "integrity": "sha512-vB+4G/jBQCAh0jelMTY3+kgFy00Hlx2f2/1zjMoH821IbplbWZOkLiTYXQkygNTzQJTq5cvwBDgn2ppHD+bglQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.1.tgz", + "integrity": "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1", + "@tybys/wasm-util": "^0.10.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + } }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true + "node_modules/@npmcli/agent": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-4.0.0.tgz", + "integrity": "sha512-kAQTcEN9E8ERLVg5AsGwLNoFb+oEG6engbqAU2P43gD4JEIkNGMHdVQ096FsOAAYpZPB0RSt0zgInKIAS1l5QA==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^11.2.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "engine.io": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", - "dev": true, - "requires": { - "accepts": "1.3.5", - "base64id": "1.0.0", - "cookie": "0.3.1", - "debug": "3.1.0", - "engine.io-parser": "2.1.2", - "uws": "9.14.0", - "ws": "3.3.3" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "3.1.0", - "engine.io-parser": "2.1.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "3.3.3", - "xmlhttprequest-ssl": "1.5.5", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "node_modules/@npmcli/fs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-5.0.0.tgz", + "integrity": "sha512-7OsC1gNORBEawOa5+j2pXN9vsicaIOH5cPXxoR6fJOmH6/EXpJB2CajXOu1fPRFun2m1lktEFX11+P89hqO/og==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "node_modules/@npmcli/git": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-7.0.1.tgz", + "integrity": "sha512-+XTFxK2jJF/EJJ5SoAzXk3qwIDfvFc5/g+bD274LZ7uY7LE8sTfG6Z8rOanPl2ZEvZWqNvmEdtXC25cE54VcoA==", "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "1.0.2" + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^9.0.0", + "ini": "^6.0.0", + "lru-cache": "^11.2.1", + "npm-pick-manifest": "^11.0.1", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "object-assign": "4.1.1", - "tapable": "0.2.8" + "license": "ISC", + "engines": { + "node": ">=16" } }, - "ent": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.0.tgz", - "integrity": "sha1-6WQhkyWiHQX0RGai9obtbOX13R0=", - "dev": true + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true + "node_modules/@npmcli/git/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "node_modules/@npmcli/installed-package-contents": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-4.0.0.tgz", + "integrity": "sha512-yNyAdkBxB72gtZ4GrwXCM0ZUedo9nIbOMKfGjt6Cu6DXf0p8y1PViZAKDC8q8kv/fufx0WTjRBdSlyrvnP7hmA==", "dev": true, - "requires": { - "prr": "1.0.1" + "license": "ISC", + "dependencies": { + "npm-bundled": "^5.0.0", + "npm-normalize-package-bin": "^5.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "node_modules/@npmcli/node-gyp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-5.0.0.tgz", + "integrity": "sha512-uuG5HZFXLfyFKqg8QypsmgLQW7smiRjVc45bqD/ofZZcR/uxEjgQU8qDPv0s9TEeMUiAAU/GC5bR6++UdTirIQ==", "dev": true, - "requires": { - "is-arrayish": "0.2.1" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es-abstract": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", - "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", + "node_modules/@npmcli/package-json": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-7.0.4.tgz", + "integrity": "sha512-0wInJG3j/K40OJt/33ax47WfWMzZTm6OQxB9cDhTt5huCP2a9g2GnlsxmfN+PulItNPIpPrZ+kfwwUil7eHcZQ==", "dev": true, - "requires": { - "es-to-primitive": "1.1.1", - "function-bind": "1.1.1", - "has": "1.0.1", - "is-callable": "1.1.3", - "is-regex": "1.0.4" + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "glob": "^13.0.0", + "hosted-git-info": "^9.0.0", + "json-parse-even-better-errors": "^5.0.0", + "proc-log": "^6.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "node_modules/@npmcli/promise-spawn": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-9.0.1.tgz", + "integrity": "sha512-OLUaoqBuyxeTqUvjA3FZFiXUfYC1alp3Sa99gW3EUDz3tZ3CbXDdcZ7qWKBzicrJleIgucoWamWH1saAmH/l2Q==", "dev": true, - "requires": { - "is-callable": "1.1.3", - "is-date-object": "1.0.1", - "is-symbol": "1.0.1" + "license": "ISC", + "dependencies": { + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es5-ext": { - "version": "0.10.41", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.41.tgz", - "integrity": "sha512-MYK02wXfwTMie5TEJWPolgOsXEmz7wKCQaGzgmRjZOoV6VLG8I5dSv2bn6AOClXhK64gnSQTQ9W9MKvx87J4gw==", + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "next-tick": "1.0.0" + "license": "ISC", + "engines": { + "node": ">=16" } }, - "es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41", - "es6-symbol": "3.1.1" + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", + "node_modules/@npmcli/redact": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-4.0.0.tgz", + "integrity": "sha512-gOBg5YHMfZy+TfHArfVogwgfBeQnKbbGo3pSUyK/gSI0AVu+pEiDVcKlQb0D8Mg1LNRZILZ6XG8I5dJ4KuAd9Q==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41", - "es6-iterator": "2.0.3", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", + "node_modules/@npmcli/run-script": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-10.0.3.tgz", + "integrity": "sha512-ER2N6itRkzWbbtVmZ9WKaWxVlKlOeBFF1/7xx+KA5J1xKa4JjUwBdb6tDpk0v1qA+d+VDwHI9qmLcXSWcmi+Rw==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^5.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "node-gyp": "^12.1.0", + "proc-log": "^6.0.0", + "which": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "es6-symbol": { + "node_modules/@npmcli/run-script/node_modules/isexe": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41" + "license": "ISC", + "engines": { + "node": ">=16" } }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41", - "es6-iterator": "2.0.3", - "es6-symbol": "3.1.1" + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", - "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", - "dev": true, - "optional": true, - "requires": { - "esprima": "3.1.3", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.6.1" - }, - "dependencies": { - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true, - "optional": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "optional": true - } - } - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.1", - "estraverse": "4.2.0" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.41" - } - }, - "eventemitter3": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz", - "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg=", - "dev": true - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "eventsource": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-0.1.6.tgz", - "integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=", - "dev": true, - "requires": { - "original": "1.0.0" - } - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "1.3.4", - "safe-buffer": "5.1.1" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.2", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - } - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-braces": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/expand-braces/-/expand-braces-0.1.2.tgz", - "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", - "dev": true, - "requires": { - "array-slice": "0.2.3", - "array-unique": "0.2.1", - "braces": "0.1.5" - }, - "dependencies": { - "braces": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-0.1.5.tgz", - "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", - "dev": true, - "requires": { - "expand-range": "0.1.1" - } - }, - "expand-range": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-0.1.1.tgz", - "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", - "dev": true, - "requires": { - "is-number": "0.1.1", - "repeat-string": "0.2.2" - } - }, - "is-number": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-0.1.1.tgz", - "integrity": "sha1-aaevEWlj1HIG7JvZtIoUIW8eOAY=", - "dev": true - }, - "repeat-string": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-0.2.2.tgz", - "integrity": "sha1-x6jTI2BoNiBZp+RlH8aITosftK4=", - "dev": true - } - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", - "dev": true, - "requires": { - "accepts": "1.3.5", - "array-flatten": "1.1.1", - "body-parser": "1.18.2", - "content-disposition": "0.5.2", - "content-type": "1.0.4", - "cookie": "0.3.1", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "1.1.2", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "finalhandler": "1.1.1", - "fresh": "0.5.2", - "merge-descriptors": "1.0.1", - "methods": "1.1.2", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "path-to-regexp": "0.1.7", - "proxy-addr": "2.0.3", - "qs": "6.5.1", - "range-parser": "1.2.0", - "safe-buffer": "5.1.1", - "send": "0.16.2", - "serve-static": "1.13.2", - "setprototypeof": "1.1.0", - "statuses": "1.4.0", - "type-is": "1.6.16", - "utils-merge": "1.0.1", - "vary": "1.1.2" - }, - "dependencies": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "1.0.0", - "is-extendable": "1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "extract-text-webpack-plugin": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-3.0.2.tgz", - "integrity": "sha512-bt/LZ4m5Rqt/Crl2HiKuAl/oqg0psx1tsTLkvWbJen1CtD+fftkZhMaQ9HOtY2gWsl2Wq+sABmMVi9z3DhKWQQ==", - "dev": true, - "requires": { - "async": "2.6.0", - "loader-utils": "1.1.0", - "schema-utils": "0.3.0", - "webpack-sources": "1.1.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "5.5.2" - } - } - } - }, - "extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz", - "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true, - "optional": true - }, - "fastparse": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", - "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", - "dev": true - }, - "faye-websocket": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", - "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", - "dev": true, - "requires": { - "websocket-driver": "0.7.0" - } - }, - "file-loader": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", - "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", - "dev": true, - "requires": { - "loader-utils": "1.1.0", - "schema-utils": "0.4.5" - } - }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "fileset": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", - "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", - "dev": true, - "requires": { - "glob": "7.1.2", - "minimatch": "3.0.4" - } - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "finalhandler": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", - "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", - "dev": true, - "requires": { - "debug": "2.6.9", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "on-finished": "2.3.0", - "parseurl": "1.3.2", - "statuses": "1.4.0", - "unpipe": "1.0.0" - } - }, - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "1.0.1", - "make-dir": "1.2.0", - "pkg-dir": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "flush-write-stream": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", - "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" - } - }, - "follow-redirects": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.0.0.tgz", - "integrity": "sha1-jjQpjL0uF28lTv/sdaHHjMhJ/Tc=", - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.9" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.18" - } - }, - "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "0.2.2" - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" - } - }, - "fs-access": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", - "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", - "dev": true, - "requires": { - "null-check": "1.0.0" - } - }, - "fs-extra": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "4.0.0", - "universalify": "0.1.1" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "iferr": "0.1.5", - "imurmurhash": "0.1.4", - "readable-stream": "2.3.5" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.3.tgz", - "integrity": "sha512-WIr7iDkdmdbxu/Gh6eKEZJL6KPE74/5MEsf2whTOFNxbIoIixogroLdKYqB6FDav4Wavh/lZdzzd3b2KxIXC5Q==", - "dev": true, - "optional": true, - "requires": { - "nan": "2.10.0", - "node-pre-gyp": "0.6.39" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.39", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "1.0.2", - "hawk": "3.1.3", - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - } - } - }, - "fstream": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", - "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "node_modules/@oxc-project/types": { + "version": "0.106.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.106.0.tgz", + "integrity": "sha512-QdsH3rZq480VnOHSHgPYOhjL8O8LBdcnSjM408BpPCCUc0JYYZPG9Gafl9i3OcGk/7137o+gweb4cCv3WAUykg==", "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.2" + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" } }, - "ftp": { - "version": "0.3.10", - "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", - "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", + "node_modules/@parcel/watcher": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.4.tgz", + "integrity": "sha512-WYa2tUVV5HiArWPB3ydlOc4R2ivq0IDrlqhMi3l7mVsFEXNcTfxYFPIHXHXIh/ca/y/V5N4E1zecyxdIBjYnkQ==", "dev": true, + "hasInstallScript": true, + "license": "MIT", "optional": true, - "requires": { - "readable-stream": "1.1.14", - "xregexp": "2.0.0" - }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true, - "optional": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "gaze": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", - "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", - "dev": true, + "detect-libc": "^2.0.3", + "is-glob": "^4.0.3", + "node-addon-api": "^7.0.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.4", + "@parcel/watcher-darwin-arm64": "2.5.4", + "@parcel/watcher-darwin-x64": "2.5.4", + "@parcel/watcher-freebsd-x64": "2.5.4", + "@parcel/watcher-linux-arm-glibc": "2.5.4", + "@parcel/watcher-linux-arm-musl": "2.5.4", + "@parcel/watcher-linux-arm64-glibc": "2.5.4", + "@parcel/watcher-linux-arm64-musl": "2.5.4", + "@parcel/watcher-linux-x64-glibc": "2.5.4", + "@parcel/watcher-linux-x64-musl": "2.5.4", + "@parcel/watcher-win32-arm64": "2.5.4", + "@parcel/watcher-win32-ia32": "2.5.4", + "@parcel/watcher-win32-x64": "2.5.4" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.4.tgz", + "integrity": "sha512-hoh0vx4v+b3BNI7Cjoy2/B0ARqcwVNrzN/n7DLq9ZB4I3lrsvhrkCViJyfTj/Qi5xM9YFiH4AmHGK6pgH1ss7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.4.tgz", + "integrity": "sha512-kphKy377pZiWpAOyTgQYPE5/XEKVMaj6VUjKT5VkNyUJlr2qZAn8gIc7CPzx+kbhvqHDT9d7EqdOqRXT6vk0zw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.4.tgz", + "integrity": "sha512-UKaQFhCtNJW1A9YyVz3Ju7ydf6QgrpNQfRZ35wNKUhTQ3dxJ/3MULXN5JN/0Z80V/KUBDGa3RZaKq1EQT2a2gg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.4.tgz", + "integrity": "sha512-Dib0Wv3Ow/m2/ttvLdeI2DBXloO7t3Z0oCp4bAb2aqyqOjKPPGrg10pMJJAQ7tt8P4V2rwYwywkDhUia/FgS+Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.4.tgz", + "integrity": "sha512-I5Vb769pdf7Q7Sf4KNy8Pogl/URRCKu9ImMmnVKYayhynuyGYMzuI4UOWnegQNa2sGpsPSbzDsqbHNMyeyPCgw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.4.tgz", + "integrity": "sha512-kGO8RPvVrcAotV4QcWh8kZuHr9bXi9a3bSZw7kFarYR0+fGliU7hd/zevhjw8fnvIKG3J9EO5G6sXNGCSNMYPQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.4.tgz", + "integrity": "sha512-KU75aooXhqGFY2W5/p8DYYHt4hrjHZod8AhcGAmhzPn/etTa+lYCDB2b1sJy3sWJ8ahFVTdy+EbqSBvMx3iFlw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.4.tgz", + "integrity": "sha512-Qx8uNiIekVutnzbVdrgSanM+cbpDD3boB1f8vMtnuG5Zau4/bdDbXyKwIn0ToqFhIuob73bcxV9NwRm04/hzHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.4.tgz", + "integrity": "sha512-UYBQvhYmgAv61LNUn24qGQdjtycFBKSK3EXr72DbJqX9aaLbtCOO8+1SkKhD/GNiJ97ExgcHBrukcYhVjrnogA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.4.tgz", + "integrity": "sha512-YoRWCVgxv8akZrMhdyVi6/TyoeeMkQ0PGGOf2E4omODrvd1wxniXP+DBynKoHryStks7l+fDAMUBRzqNHrVOpg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.4.tgz", + "integrity": "sha512-iby+D/YNXWkiQNYcIhg8P5hSjzXEHaQrk2SLrWOUD7VeC4Ohu0WQvmV+HDJokZVJ2UjJ4AGXW3bx7Lls9Ln4TQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.4.tgz", + "integrity": "sha512-vQN+KIReG0a2ZDpVv8cgddlf67J8hk1WfZMMP7sMeZmJRSmEax5xNDNWKdgqSe2brOKTQQAs3aCCUal2qBHAyg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.4.tgz", + "integrity": "sha512-3A6efb6BOKwyw7yk9ro2vus2YTt2nvcd56AuzxdMiVOxL9umDyN5PKkKfZ/gZ9row41SjVmTVQNWQhaRRGpOKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, - "requires": { - "globule": "1.2.0" + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" } }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", "dev": true, + "license": "MIT", "optional": true }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-mWj5eE4Qc8TbPdGGaaLvBb9XfDPvE1EmZkJQgiGKwchkWH4oAJcRAKMTw7ZHnb1L+t7Ah41sBkAecaIsuUgsug==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-wFxUymI/5R8bH8qZFYDfAxAN9CyISEIYke+95oZPiv6EWo88aa5rskjVcCpKA532R+klFmdqjbbaD56GNmTF4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-beta.58.tgz", + "integrity": "sha512-ybp3MkPj23VDV9PhtRwdU5qrGhlViWRV5BjKwO6epaSlUD5lW0WyY+roN3ZAzbma/9RrMTgZ/a/gtQq8YXOcqw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-beta.58.tgz", + "integrity": "sha512-Evxj3yh7FWvyklUYZa0qTVT9N2zX9TPDqGF056hl8hlCZ9/ndQ2xMv6uw9PD1VlLpukbsqL+/C6M0qwipL0QMg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-beta.58.tgz", + "integrity": "sha512-tYeXprDOrEgVHUbPXH6MPso4cM/c6RTkmJNICMQlYdki4hGMh92aj3yU6CKs+4X5gfG0yj5kVUw/L4M685SYag==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", "optional": true, - "requires": { - "is-property": "1.0.2" + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-beta.58.tgz", + "integrity": "sha512-N78vmZzP6zG967Ohr+MasCjmKtis0geZ1SOVmxrA0/bklTQSzH5kHEjW5Qn+i1taFno6GEre1E40v0wuWsNOQw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-beta.58.tgz", + "integrity": "sha512-l+p4QVtG72C7wI2SIkNQw/KQtSjuYwS3rV6AKcWrRBF62ClsFUcif5vLaZIEbPrCXu5OFRXigXFJnxYsVVZqdQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-beta.58.tgz", + "integrity": "sha512-urzJX0HrXxIh0FfxwWRjfPCMeInU9qsImLQxHBgLp5ivji1EEUnOfux8KxPPnRQthJyneBrN2LeqUix9DYrNaQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-beta.58.tgz", + "integrity": "sha512-7ijfVK3GISnXIwq/1FZo+KyAUJjL3kWPJ7rViAL6MWeEBhEgRzJ0yEd9I8N9aut8Y8ab+EKFJyRNMWZuUBwQ0A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-beta.58.tgz", + "integrity": "sha512-/m7sKZCS+cUULbzyJTIlv8JbjNohxbpAOA6cM+lgWgqVzPee3U6jpwydrib328JFN/gF9A99IZEnuGYqEDJdww==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-beta.58.tgz", + "integrity": "sha512-6SZk7zMgv+y3wFFQ9qE5P9NnRHcRsptL1ypmudD26PDY+PvFCvfHRkJNfclWnvacVGxjowr7JOL3a9fd1wWhUw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^1.1.1" + }, + "engines": { + "node": ">=14.0.0" } }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "get-uri": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz", - "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==", + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-beta.58.tgz", + "integrity": "sha512-sFqfYPnBZ6xBhMkadB7UD0yjEDRvs7ipR3nCggblN+N4ODCXY6qhg/bKL39+W+dgQybL7ErD4EGERVbW9DAWvg==", + "cpu": [ + "arm64" + ], "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-beta.58.tgz", + "integrity": "sha512-AnFWJdAqB8+IDPcGrATYs67Kik/6tnndNJV2jGRmwlbeNiQQ8GhRJU8ETRlINfII0pqi9k4WWLnb00p1QCxw/Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", "optional": true, - "requires": { - "data-uri-to-buffer": "1.2.0", - "debug": "2.6.9", - "extend": "3.0.1", - "file-uri-to-path": "1.0.0", - "ftp": "0.3.10", - "readable-stream": "2.3.5" + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" } }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "node_modules/@rolldown/pluginutils": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.58.tgz", + "integrity": "sha512-qWhDs6yFGR5xDfdrwiSa3CWGIHxD597uGE/A9xGqytBjANvh4rLCTTkq7szhMV4+Ygh+PMS90KVJ8xWG/TkX4w==", "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } + "license": "MIT" }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.3.tgz", + "integrity": "sha512-qyX8+93kK/7R5BEXPC2PjUt0+fS/VO2BVHjEHyIEWiYn88rcRBHmdLgoJjktBltgAf+NY7RfCGB1SoyKS/p9kg==", + "cpu": [ + "arm" + ], "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.3.tgz", + "integrity": "sha512-6sHrL42bjt5dHQzJ12Q4vMKfN+kUnZ0atHHnv4V0Wd9JMTk7FDzSY35+7qbz3ypQYMBPANbpGK7JpnWNnhGt8g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.3.tgz", + "integrity": "sha512-1ht2SpGIjEl2igJ9AbNpPIKzb1B5goXOcmtD0RFxnwNuMxqkR6AUaaErZz+4o+FKmzxcSNBOLrzsICZVNYa1Rw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.3.tgz", + "integrity": "sha512-FYZ4iVunXxtT+CZqQoPVwPhH7549e/Gy7PIRRtq4t5f/vt54pX6eG9ebttRH6QSH7r/zxAFA4EZGlQ0h0FvXiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.3.tgz", + "integrity": "sha512-M/mwDCJ4wLsIgyxv2Lj7Len+UMHd4zAXu4GQ2UaCdksStglWhP61U3uowkaYBQBhVoNpwx5Hputo8eSqM7K82Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.3.tgz", + "integrity": "sha512-5jZT2c7jBCrMegKYTYTpni8mg8y3uY8gzeq2ndFOANwNuC/xJbVAoGKR9LhMDA0H3nIhvaqUoBEuJoICBudFrA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.3.tgz", + "integrity": "sha512-YeGUhkN1oA+iSPzzhEjVPS29YbViOr8s4lSsFaZKLHswgqP911xx25fPOyE9+khmN6W4VeM0aevbDp4kkEoHiA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.3.tgz", + "integrity": "sha512-eo0iOIOvcAlWB3Z3eh8pVM8hZ0oVkK3AjEM9nSrkSug2l15qHzF3TOwT0747omI6+CJJvl7drwZepT+re6Fy/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.3.tgz", + "integrity": "sha512-DJay3ep76bKUDImmn//W5SvpjRN5LmK/ntWyeJs/dcnwiiHESd3N4uteK9FDLf0S0W8E6Y0sVRXpOCoQclQqNg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.3.tgz", + "integrity": "sha512-BKKWQkY2WgJ5MC/ayvIJTHjy0JUGb5efaHCUiG/39sSUvAYRBaO3+/EK0AZT1RF3pSj86O24GLLik9mAYu0IJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.3.tgz", + "integrity": "sha512-Q9nVlWtKAG7ISW80OiZGxTr6rYtyDSkauHUtvkQI6TNOJjFvpj4gcH+KaJihqYInnAzEEUetPQubRwHef4exVg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.3.tgz", + "integrity": "sha512-2H5LmhzrpC4fFRNwknzmmTvvyJPHwESoJgyReXeFoYYuIDfBhP29TEXOkCJE/KxHi27mj7wDUClNq78ue3QEBQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.3.tgz", + "integrity": "sha512-9S542V0ie9LCTznPYlvaeySwBeIEa7rDBgLHKZ5S9DBgcqdJYburabm8TqiqG6mrdTzfV5uttQRHcbKff9lWtA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.3.tgz", + "integrity": "sha512-ukxw+YH3XXpcezLgbJeasgxyTbdpnNAkrIlFGDl7t+pgCxZ89/6n1a+MxlY7CegU+nDgrgdqDelPRNQ/47zs0g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.3.tgz", + "integrity": "sha512-Iauw9UsTTvlF++FhghFJjqYxyXdggXsOqGpFBylaRopVpcbfyIIsNvkf9oGwfgIcf57z3m8+/oSYTo6HutBFNw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.3.tgz", + "integrity": "sha512-3OqKAHSEQXKdq9mQ4eajqUgNIK27VZPW3I26EP8miIzuKzCJ3aW3oEn2pzF+4/Hj/Moc0YDsOtBgT5bZ56/vcA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.3.tgz", + "integrity": "sha512-0CM8dSVzVIaqMcXIFej8zZrSFLnGrAE8qlNbbHfTw1EEPnFTg1U1ekI0JdzjPyzSfUsHWtodilQQG/RA55berA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.3.tgz", + "integrity": "sha512-+fgJE12FZMIgBaKIAGd45rxf+5ftcycANJRWk8Vz0NnMTM5rADPGuRFTYar+Mqs560xuART7XsX2lSACa1iOmQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.3.tgz", + "integrity": "sha512-tMD7NnbAolWPzQlJQJjVFh/fNH3K/KnA7K8gv2dJWCwwnaK6DFCYST1QXYWfu5V0cDwarWC8Sf/cfMHniNq21A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.3.tgz", + "integrity": "sha512-u5KsqxOxjEeIbn7bUK1MPM34jrnPwjeqgyin4/N6e/KzXKfpE9Mi0nCxcQjaM9lLmPcHmn/xx1yOjgTMtu1jWQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.3.tgz", + "integrity": "sha512-vo54aXwjpTtsAnb3ca7Yxs9t2INZg7QdXN/7yaoG7nPGbOBXYXQY41Km+S1Ov26vzOAzLcAjmMdjyEqS1JkVhw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.3.tgz", + "integrity": "sha512-HI+PIVZ+m+9AgpnY3pt6rinUdRYrGHvmVdsNQ4odNqQ/eRF78DVpMR7mOq7nW06QxpczibwBmeQzB68wJ+4W4A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.3.tgz", + "integrity": "sha512-vRByotbdMo3Wdi+8oC2nVxtc3RkkFKrGaok+a62AT8lz/YBuQjaVYAS5Zcs3tPzW43Vsf9J0wehJbUY5xRSekA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.3.tgz", + "integrity": "sha512-POZHq7UeuzMJljC5NjKi8vKMFN6/5EOqcX1yGntNLp7rUTpBAXQ1hW8kWPFxYLv07QMcNM75xqVLGPWQq6TKFA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.3.tgz", + "integrity": "sha512-aPFONczE4fUFKNXszdvnd2GqKEYQdV5oEsIbKPujJmWlCI9zEsv1Otig8RKK+X9bed9gFUN6LAeN4ZcNuu4zjg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", + "node_modules/@schematics/angular": { + "version": "21.1.0", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-21.1.0.tgz", + "integrity": "sha512-gXf3gO5SeU+tiPHxXeQvdbua4C4/V+KH43JH2PYPxaNCD2HGo1uV0pfyNSNgcVF21voKlbAQ13YRrNDh7z5Kig==", "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "21.1.0", + "@angular-devkit/schematics": "21.1.0", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "node_modules/@sigstore/bundle": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-4.0.0.tgz", + "integrity": "sha512-NwCl5Y0V6Di0NexvkTqdoVfmjTaQwoLM236r89KEojGmq/jMls8S+zb7yOwAPdXvbwfKDlP+lmXgAL4vKSQT+A==", "dev": true, - "requires": { - "is-glob": "2.0.1" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-7.1.1.tgz", - "integrity": "sha1-+yzP+UAfhgCUXfral0QMypcrhoA=", + "node_modules/@sigstore/core": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-3.1.0.tgz", + "integrity": "sha512-o5cw1QYhNQ9IroioJxpzexmPjfCe7gzafd2RY3qnMpxr4ZEja+Jad/U8sgFpaue6bOaF+z7RVkyKVV44FN+N8A==", "dev": true, - "requires": { - "array-union": "1.0.2", - "dir-glob": "2.0.0", - "glob": "7.1.2", - "ignore": "3.3.7", - "pify": "3.0.0", - "slash": "1.0.0" + "license": "Apache-2.0", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "globule": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", - "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "node_modules/@sigstore/protobuf-specs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.5.0.tgz", + "integrity": "sha512-MM8XIwUjN2bwvCg1QvrMtbBmpcSHrkhFSCu1D11NyPvDQ25HEc4oG5/OcQfd/Tlf/OxmKWERDj0zGE23jQaMwA==", "dev": true, - "optional": true, - "requires": { - "glob": "7.1.2", - "lodash": "4.17.5", - "minimatch": "3.0.4" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "handle-thing": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-1.2.5.tgz", - "integrity": "sha1-/Xqtcmvxpf0W38KbL3pmAdJxOcQ=", - "dev": true - }, - "handlebars": { - "version": "4.0.11", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz", - "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=", - "dev": true, - "requires": { - "async": "1.5.2", - "optimist": "0.6.1", - "source-map": "0.4.4", - "uglify-js": "2.8.29" - }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true, - "optional": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "optional": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - } - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "optional": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - } - } - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "optional": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", + "node_modules/@sigstore/sign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-4.1.0.tgz", + "integrity": "sha512-Vx1RmLxLGnSUqx/o5/VsCjkuN5L7y+vxEEwawvc7u+6WtX2W4GNa7b9HEjmcRWohw/d6BpATXmvOwc78m+Swdg==", "dev": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - }, + "license": "Apache-2.0", "dependencies": { - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - } - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.1" + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "make-fetch-happen": "^15.0.3", + "proc-log": "^6.1.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "node_modules/@sigstore/tuf": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-4.0.1.tgz", + "integrity": "sha512-OPZBg8y5Vc9yZjmWCHrlWPMBqW5yd8+wFNl+thMdtcWz3vjVSoJQutF8YkrzI0SLGnkuFof4HSsWUhXrf219Lw==", "dev": true, - "requires": { - "ansi-regex": "2.1.1" + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.5.0", + "tuf-js": "^4.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "has-binary2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz", - "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=", + "node_modules/@sigstore/verify": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-3.1.0.tgz", + "integrity": "sha512-mNe0Iigql08YupSOGv197YdHpPPr+EzDZmfCgMc7RPNaZTw5aLN01nBl6CHJOh3BGtnMIj83EeN4butBchc8Ag==", "dev": true, - "requires": { - "isarray": "2.0.1" - }, + "license": "Apache-2.0", "dependencies": { - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - } + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "has-cors": { + "node_modules/@standard-schema/spec": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "2.0.6", - "has-values": "1.0.0", - "isobject": "3.0.1" - }, - "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "license": "MIT" + }, + "node_modules/@tauri-apps/api": { + "version": "2.9.1", + "resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-2.9.1.tgz", + "integrity": "sha512-IGlhP6EivjXHepbBic618GOmiWe4URJiIeZFlB7x3czM0yDHHYviH1Xvoiv4FefdkQtn6v7TuwWCRfOGdnVUGw==", + "license": "Apache-2.0 OR MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.6.tgz", + "integrity": "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.9.6", + "@tauri-apps/cli-darwin-x64": "2.9.6", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", + "@tauri-apps/cli-linux-arm64-musl": "2.9.6", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-musl": "2.9.6", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", + "@tauri-apps/cli-win32-x64-msvc": "2.9.6" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.9.6.tgz", + "integrity": "sha512-gf5no6N9FCk1qMrti4lfwP77JHP5haASZgVbBgpZG7BUepB3fhiLCXGUK8LvuOjP36HivXewjg72LTnPDScnQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.9.6.tgz", + "integrity": "sha512-oWh74WmqbERwwrwcueJyY6HYhgCksUc6NT7WKeXyrlY/FPmNgdyQAgcLuTSkhRFuQ6zh4Np1HZpOqCTpeZBDcw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.9.6.tgz", + "integrity": "sha512-/zde3bFroFsNXOHN204DC2qUxAcAanUjVXXSdEGmhwMUZeAQalNj5cz2Qli2elsRjKN/hVbZOJj0gQ5zaYUjSg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.9.6.tgz", + "integrity": "sha512-pvbljdhp9VOo4RnID5ywSxgBs7qiylTPlK56cTk7InR3kYSTJKYMqv/4Q/4rGo/mG8cVppesKIeBMH42fw6wjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.9.6.tgz", + "integrity": "sha512-02TKUndpodXBCR0oP//6dZWGYcc22Upf2eP27NvC6z0DIqvkBBFziQUcvi2n6SrwTRL0yGgQjkm9K5NIn8s6jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.9.6.tgz", + "integrity": "sha512-fmp1hnulbqzl1GkXl4aTX9fV+ubHw2LqlLH1PE3BxZ11EQk+l/TmiEongjnxF0ie4kV8DQfDNJ1KGiIdWe1GvQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.9.6.tgz", + "integrity": "sha512-vY0le8ad2KaV1PJr+jCd8fUF9VOjwwQP/uBuTJvhvKTloEwxYA/kAjKK9OpIslGA9m/zcnSo74czI6bBrm2sYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.9.6.tgz", + "integrity": "sha512-TOEuB8YCFZTWVDzsO2yW0+zGcoMiPPwcUgdnW1ODnmgfwccpnihDRoks+ABT1e3fHb1ol8QQWsHSCovb3o2ENQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.9.6.tgz", + "integrity": "sha512-ujmDGMRc4qRLAnj8nNG26Rlz9klJ0I0jmZs2BPpmNNf0gM/rcVHhqbEkAaHPTBVIrtUdf7bGvQAD2pyIiUrBHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.9.6.tgz", + "integrity": "sha512-S4pT0yAJgFX8QRCyKA1iKjZ9Q/oPjCZf66A/VlG5Yw54Nnr88J1uBpmenINbXxzyhduWrIXBaUbEY1K80ZbpMg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.6.tgz", + "integrity": "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" } }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "node_modules/@tauri-apps/plugin-dialog": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-dialog/-/plugin-dialog-2.6.0.tgz", + "integrity": "sha512-q4Uq3eY87TdcYzXACiYSPhmpBA76shgmQswGkSVio4C82Sz2W4iehe9TnKYwbq7weHiL88Yw19XZm7v28+Micg==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" } }, - "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "dev": true, - "requires": { - "inherits": "2.0.3" + "node_modules/@tauri-apps/plugin-fs": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/@tauri-apps/plugin-fs/-/plugin-fs-2.4.5.tgz", + "integrity": "sha512-dVxWWGE6VrOxC7/jlhyE+ON/Cc2REJlM35R3PJX3UvFw2XwYhLGQVAIyrehenDdKjotipjYEVc4YjOl3qq90fA==", + "license": "MIT OR Apache-2.0", + "dependencies": { + "@tauri-apps/api": "^2.8.0" } }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", "dev": true, - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" } }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", + "node_modules/@tufjs/models": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-4.1.0.tgz", + "integrity": "sha512-Y8cK9aggNRsqJVaKUlEYs4s7CvQ1b1ta2DVPyAimb0I2qhzjNk+A+mxvll/klL0RlfuIUei8BF7YWiua4kQqww==", "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^10.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", - "dev": true - }, - "hipchat-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/hipchat-notifier/-/hipchat-notifier-1.1.0.tgz", - "integrity": "sha1-ttJJdVQ3wZEII2d5nTupoPI7Ix4=", + "node_modules/@tybys/wasm-util": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz", + "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==", "dev": true, + "license": "MIT", "optional": true, - "requires": { - "lodash": "4.17.5", - "request": "2.81.0" + "dependencies": { + "tslib": "^2.4.0" } }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, - "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "homedir-polyfill": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", - "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", "dev": true, - "requires": { - "parse-passwd": "1.0.0" - } + "license": "MIT" }, - "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", - "dev": true + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "node_modules/@types/node": { + "version": "24.10.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.10.9.tgz", + "integrity": "sha512-ne4A0IpG3+2ETuREInjPNhUGis1SFjv1d5asp8MzEAGtOZeTeHVDOYqOgqfhvseqg/iXty2hjBf1zAOb7RNiNw==", "dev": true, - "requires": { - "inherits": "2.0.3", - "obuf": "1.1.2", - "readable-stream": "2.3.5", - "wbuf": "1.7.3" + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" } }, - "html-entities": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.2.1.tgz", - "integrity": "sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=", - "dev": true - }, - "html-minifier": { - "version": "3.5.12", - "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.12.tgz", - "integrity": "sha512-+N778qLf0RWBscD0TPGoYdeGNDZ0s76/0pQhY1/409EOudcENkm9IbSkk37RDyPdg/09GVHTKotU4ya93RF1Gg==", - "dev": true, - "requires": { - "camel-case": "3.0.0", - "clean-css": "4.1.11", - "commander": "2.15.1", - "he": "1.1.1", - "ncname": "1.0.0", - "param-case": "2.1.1", - "relateurl": "0.2.7", - "uglify-js": "3.3.16" - } - }, - "html-webpack-plugin": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", - "integrity": "sha1-f5xCG36pHsRg9WUn1430hO51N9U=", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "html-minifier": "3.5.12", - "loader-utils": "0.2.17", - "lodash": "4.17.5", - "pretty-error": "2.1.1", - "toposort": "1.0.6" - }, - "dependencies": { - "loader-utils": { - "version": "0.2.17", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", - "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", - "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1", - "object-assign": "4.1.1" - } - } + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-2.1.0.tgz", + "integrity": "sha512-dOxxrhgyDIEUADhb/8OlV9JIqYLgos03YorAueTIeOUskLJSEsfwCByjbu98ctXitUN3znXKp0bYD/WHSudCeA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "peerDependencies": { + "vite": "^6.0.0 || ^7.0.0" } }, - "htmlescape": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", - "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", - "dev": true - }, - "htmlparser2": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.3.0.tgz", - "integrity": "sha1-zHDQWln2VC5D8OaFyYLhTJJKnv4=", - "dev": true, - "requires": { - "domelementtype": "1.3.0", - "domhandler": "2.1.0", - "domutils": "1.1.6", - "readable-stream": "1.0.34" - }, - "dependencies": { - "domutils": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.1.6.tgz", - "integrity": "sha1-vdw94Jm5ou+sxRxiPyj0FuzFdIU=", - "dev": true, - "requires": { - "domelementtype": "1.3.0" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "0.0.1", - "string_decoder": "0.10.31" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } + "node_modules/@vitest/expect": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.0.17.tgz", + "integrity": "sha512-mEoqP3RqhKlbmUmntNDDCJeTDavDR+fVYkSOw8qRwJFaW/0/5zA9zFeTrHqNtcmwh6j26yMmwx2PqUDPzt5ZAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "chai": "^6.2.1", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "node_modules/@vitest/mocker": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.0.17.tgz", + "integrity": "sha512-+ZtQhLA3lDh1tI2wxe3yMsGzbp7uuJSWBM1iTIKCbppWTSBN09PUC+L+fyNlQApQoR+Ps8twt2pbSSXg2fQVEQ==", "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": "1.4.0" - }, + "license": "MIT", "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true + "@vitest/spy": "4.0.17", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0-0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true + "vite": { + "optional": true } } }, - "http-parser-js": { - "version": "0.4.11", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.11.tgz", - "integrity": "sha512-QCR5O2AjjMW8Mo4HyI1ctFcv+O99j/0g367V3YoVnrNw5hkDvAWZD0lWGcc+F4yN3V55USPCVix4efb75HxFfA==", - "dev": true - }, - "http-proxy": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz", - "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=", + "node_modules/@vitest/pretty-format": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.0.17.tgz", + "integrity": "sha512-Ah3VAYmjcEdHg6+MwFE17qyLqBHZ+ni2ScKCiW2XrlSBV4H3Z7vYfPfz7CWQ33gyu76oc0Ai36+kgLU3rfF4nw==", "dev": true, - "requires": { - "eventemitter3": "1.2.0", - "requires-port": "1.0.0" + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "http-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz", - "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=", + "node_modules/@vitest/runner": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.0.17.tgz", + "integrity": "sha512-JmuQyf8aMWoo/LmNFppdpkfRVHJcsgzkbCA+/Bk7VfNH7RE6Ut2qxegeyx2j3ojtJtKIbIGy3h+KxGfYfk28YQ==", "dev": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1" + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.0.17", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "http-proxy-middleware": { - "version": "0.17.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz", - "integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=", + "node_modules/@vitest/snapshot": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.0.17.tgz", + "integrity": "sha512-npPelD7oyL+YQM2gbIYvlavlMVWUfNNGZPcu0aEUQXt7FXTuqhmgiYupPnAanhKvyP6Srs2pIbWo30K0RbDtRQ==", "dev": true, - "requires": { - "http-proxy": "1.16.2", - "is-glob": "3.1.0", - "lodash": "4.17.5", - "micromatch": "2.3.11" - }, + "license": "MIT", "dependencies": { - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } + "@vitest/pretty-format": "4.0.17", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", + "node_modules/@vitest/spy": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.0.17.tgz", + "integrity": "sha512-I1bQo8QaP6tZlTomQNWKJE6ym4SHf3oLS7ceNjozxxgzavRAgZDc06T7kD8gb9bXKEgcLNt00Z+kZO6KaJ62Ew==", "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.1", - "sshpk": "1.14.1" + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" } }, - "httpntlm": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/httpntlm/-/httpntlm-1.6.1.tgz", - "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", + "node_modules/@vitest/utils": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.0.17.tgz", + "integrity": "sha512-RG6iy+IzQpa9SB8HAFHJ9Y+pTzI+h8553MrciN9eC6TFBErqrQaTas4vG+MVj8S4uKk8uTT2p0vgZPnTdxd96w==", "dev": true, - "requires": { - "httpreq": "0.4.24", - "underscore": "1.7.0" + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.0.17", + "tinyrainbow": "^3.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" } }, - "httpreq": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/httpreq/-/httpreq-0.4.24.tgz", - "integrity": "sha1-QzX/2CzZaWaKOUZckprGHWOTYn8=", - "dev": true - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "https-proxy-agent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz", - "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=", - "dev": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "ieee754": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", - "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "ignore": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", - "dev": true - }, - "image-size": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", - "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=", + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", "dev": true, - "optional": true + "license": "BSD-2-Clause" }, - "import-local": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "node_modules/abbrev": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-4.0.0.tgz", + "integrity": "sha512-a1wflyaL0tHtJSmLSOVybYhy22vRih4eduhhrkcjgrWGnRfrZtovJ2FRjxuTtkkj47O/baf0R86QU5OuYpz8fA==", "dev": true, - "requires": { - "pkg-dir": "2.0.0", - "resolve-cwd": "2.0.0" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "in-publish": { + "node_modules/accepts": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", "dev": true, - "requires": { - "repeating": "2.0.1" + "license": "MIT", + "engines": { + "node": ">= 14" } }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "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" + } }, - "inflection": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.10.0.tgz", - "integrity": "sha1-W//LEZetPoEFD44X4hZoCH7p6y8=", + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "node_modules/algoliasearch": { + "version": "5.46.2", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.46.2.tgz", + "integrity": "sha512-qqAXW9QvKf2tTyhpDA4qXv1IfBwD2eduSW6tUEBFIfCeE9gn9HQ9I5+MaKoenRuHrzk5sQoNh1/iof8mY7uD6Q==", "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.12.2", + "@algolia/client-abtesting": "5.46.2", + "@algolia/client-analytics": "5.46.2", + "@algolia/client-common": "5.46.2", + "@algolia/client-insights": "5.46.2", + "@algolia/client-personalization": "5.46.2", + "@algolia/client-query-suggestions": "5.46.2", + "@algolia/client-search": "5.46.2", + "@algolia/ingestion": "1.46.2", + "@algolia/monitoring": "1.46.2", + "@algolia/recommend": "5.46.2", + "@algolia/requester-browser-xhr": "5.46.2", + "@algolia/requester-fetch": "5.46.2", + "@algolia/requester-node-http": "5.46.2" + }, + "engines": { + "node": ">= 14.0.0" } }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true + "node_modules/ansi-escapes": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.2.0.tgz", + "integrity": "sha512-g6LhBsl+GBPRWGWsBtutpzBYuIIdBkLEvad5C/va/74Db018+5TZiyA26cZJAr3Rft5lprVqOIPxf5Vid6tqAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } }, - "inline-source-map": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", - "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", "dev": true, - "requires": { - "source-map": "0.5.7" + "license": "MIT", + "engines": { + "node": ">=12" } }, - "insert-module-globals": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.4.tgz", - "integrity": "sha512-Z/sfx2KOKyHQ3U4X3fnXn4Ms1Opa9pGvEfm8j6xKHE6oVqc1dMwVgBVxmj3yIrMtWTl8HYoy12rkhrR8MYym6A==", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "combine-source-map": "0.7.2", - "concat-stream": "1.6.2", - "is-buffer": "1.1.6", - "lexical-scope": "1.2.0", - "process": "0.11.10", - "through2": "2.0.3", - "xtend": "4.0.1" - }, - "dependencies": { - "combine-source-map": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", - "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", - "dev": true, - "requires": { - "convert-source-map": "1.1.3", - "inline-source-map": "0.6.2", - "lodash.memoize": "3.0.4", - "source-map": "0.5.7" - } - }, - "convert-source-map": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", - "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", - "dev": true - } + "node_modules/awesome-phonenumber": { + "version": "2.73.0", + "resolved": "https://registry.npmjs.org/awesome-phonenumber/-/awesome-phonenumber-2.73.0.tgz", + "integrity": "sha512-zirkzWFUheNnnPY1QE05PQd+5drn+5kVy76gZ3WyXnLwzXOguw6sqksyZGO1qyNnYj3Y/SDITXnS/TCk/hJXpQ==", + "license": "MIT", + "engines": { + "node": ">=12" } }, - "internal-ip": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-1.2.0.tgz", - "integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=", + "node_modules/baseline-browser-mapping": { + "version": "2.9.17", + "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.9.17.tgz", + "integrity": "sha512-agD0MgJFUP/4nvjqzIB29zRPUuCF7Ge6mEv9s8dHrtYD7QWXRcx75rOADE/d5ah1NI+0vkDl0yorDd5U852IQQ==", "dev": true, - "requires": { - "meow": "3.7.0" + "license": "Apache-2.0", + "bin": { + "baseline-browser-mapping": "dist/cli.js" } }, - "interpret": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", - "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", - "dev": true + "node_modules/beasties": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.5.tgz", + "integrity": "sha512-NaWu+f4YrJxEttJSm16AzMIFtVldCvaJ68b1L098KpqXmxt9xOLtKoLkKxb8ekhOrLqEJAbvT6n6SEvB/sac7A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^6.0.0", + "css-what": "^7.0.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "node_modules/bidi-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/bidi-js/-/bidi-js-1.0.3.tgz", + "integrity": "sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==", "dev": true, - "requires": { - "loose-envify": "1.3.1" + "license": "MIT", + "dependencies": { + "require-from-string": "^2.0.2" } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ipaddr.js": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", - "dev": true - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "node_modules/body-parser": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "dev": true, - "requires": { - "kind-of": "6.0.2" - }, + "license": "MIT", "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.1", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "node_modules/browserslist": { + "version": "4.28.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", + "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", "dev": true, - "requires": { - "binary-extensions": "1.11.0" + "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": { + "baseline-browser-mapping": "^2.9.0", + "caniuse-lite": "^1.0.30001759", + "electron-to-chromium": "^1.5.263", + "node-releases": "^2.0.27", + "update-browserslist-db": "^1.2.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, - "requires": { - "builtin-modules": "1.1.1" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", - "dev": true - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "node_modules/cacache": { + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-20.0.3.tgz", + "integrity": "sha512-3pUp4e8hv07k1QlijZu6Kn7c9+ZpWWk4j3F8N3xPuCExULobqJydKYOTj1FTq58srkJsXvO7LbGAH4C0ZU3WGw==", "dev": true, - "requires": { - "kind-of": "6.0.2" - }, + "license": "ISC", "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "@npmcli/fs": "^5.0.0", + "fs-minipass": "^3.0.0", + "glob": "^13.0.0", + "lru-cache": "^11.1.0", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^13.0.0", + "unique-filename": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "node_modules/cacache/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } }, - "is-descriptor": { + "node_modules/call-bind-apply-helpers": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "dev": true, - "requires": { - "is-accessor-descriptor": "1.0.0", - "is-data-descriptor": "1.0.0", - "kind-of": "6.0.2" + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", - "dev": true + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "license": "MIT", + "engines": { + "node": ">=6" + } }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true + "node_modules/caniuse-lite": { + "version": "1.0.30001765", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001765.tgz", + "integrity": "sha512-LWcNtSyZrakjECqmpP4qdg0MMGdN368D7X8XvvAqOcqMv0RxnlqVKZl2V6/mBR68oYMxOZPLw/gO7DuisMHUvQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", "dev": true, - "requires": { - "is-primitive": "2.0.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true + "node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "node_modules/chokidar": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-5.0.0.tgz", + "integrity": "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==", "dev": true, - "requires": { - "number-is-nan": "1.0.1" + "license": "MIT", + "dependencies": { + "readdirp": "^5.0.0" + }, + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", "dev": true, - "requires": { - "number-is-nan": "1.0.1" + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", "dev": true, - "requires": { - "is-extglob": "1.0.0" + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-my-ip-valid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "node_modules/cli-spinners": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-3.4.0.tgz", + "integrity": "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==", "dev": true, - "optional": true + "license": "MIT", + "engines": { + "node": ">=18.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "is-my-json-valid": { - "version": "2.17.2", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", - "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "node_modules/cli-truncate": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.1.1.tgz", + "integrity": "sha512-SroPvNHxUnk+vIW/dOSfNqdy1sPEFkrTk6TUtqLCnBlo3N7TNYYkzzN7uSD6+jVjrdO4+p8nH7JzH6cIvUem6A==", "dev": true, - "optional": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "is-my-ip-valid": "1.0.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" + "license": "MIT", + "dependencies": { + "slice-ansi": "^7.1.0", + "string-width": "^8.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", "dev": true, - "requires": { - "kind-of": "3.2.2" + "license": "ISC", + "engines": { + "node": ">= 12" } }, - "is-odd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", "dev": true, - "requires": { - "is-number": "4.0.0" - }, + "license": "ISC", "dependencies": { - "is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true - } + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20" } }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "node_modules/cliui/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "requires": { - "is-path-inside": "1.0.1" + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "is-path-inside": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", - "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, - "requires": { - "path-is-inside": "1.0.2" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, - "requires": { - "isobject": "3.0.1" - }, + "license": "MIT", "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" } }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true, - "optional": true + "license": "MIT" }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "dev": true, - "requires": { - "has": "1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true + "license": "MIT" }, - "is-symbol": { + "node_modules/content-disposition": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "isbinaryfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-3.0.2.tgz", - "integrity": "sha1-Sj6XTsDLqQBNP8bN5yCeppNopiE=", - "dev": true + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "dev": true, - "requires": { - "isarray": "1.0.0" + "license": "MIT", + "engines": { + "node": ">=6.6.0" } }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" }, - "istanbul-api": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", - "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", - "dev": true, - "requires": { - "async": "2.6.0", - "compare-versions": "3.1.0", - "fileset": "2.0.3", - "istanbul-lib-coverage": "1.2.0", - "istanbul-lib-hook": "1.2.0", - "istanbul-lib-instrument": "1.10.1", - "istanbul-lib-report": "1.1.4", - "istanbul-lib-source-maps": "1.2.4", - "istanbul-reports": "1.3.0", - "js-yaml": "3.11.0", - "mkdirp": "0.5.1", - "once": "1.4.0" - } - }, - "istanbul-instrumenter-loader": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-instrumenter-loader/-/istanbul-instrumenter-loader-3.0.0.tgz", - "integrity": "sha512-alLSEFX06ApU75sm5oWcaVNaiss/bgMRiWTct3g0P0ZZTKjR+6QiCcuVOKDI1kWJgwHEnIXsv/dWm783kPpmtw==", + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, - "requires": { - "convert-source-map": "1.5.1", - "istanbul-lib-instrument": "1.10.1", - "loader-utils": "1.1.0", - "schema-utils": "0.3.0" - }, + "license": "MIT", "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "5.5.2" - } - } + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" } }, - "istanbul-lib-coverage": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", - "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", - "dev": true + "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": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } }, - "istanbul-lib-hook": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz", - "integrity": "sha512-p3En6/oGkFQV55Up8ZPC2oLxvgSxD8CzA0yBrhRZSh3pfv3OFj9aSGVC0yoerAi/O4u7jUVnOGVX1eVFM+0tmQ==", + "node_modules/css-select": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-6.0.0.tgz", + "integrity": "sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==", "dev": true, - "requires": { - "append-transform": "0.4.0" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^7.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "nth-check": "^2.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "istanbul-lib-instrument": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", - "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "node_modules/css-tree": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-3.1.0.tgz", + "integrity": "sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w==", "dev": true, - "requires": { - "babel-generator": "6.26.1", - "babel-template": "6.26.0", - "babel-traverse": "6.26.0", - "babel-types": "6.26.0", - "babylon": "6.18.0", - "istanbul-lib-coverage": "1.2.0", - "semver": "5.5.0" + "license": "MIT", + "dependencies": { + "mdn-data": "2.12.2", + "source-map-js": "^1.0.1" + }, + "engines": { + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, - "istanbul-lib-report": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", - "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "node_modules/css-what": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-7.0.0.tgz", + "integrity": "sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==", "dev": true, - "requires": { - "istanbul-lib-coverage": "1.2.0", - "mkdirp": "0.5.1", - "path-parse": "1.0.5", - "supports-color": "3.2.3" + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" }, - "dependencies": { - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "supports-color": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", - "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", - "dev": true, - "requires": { - "has-flag": "1.0.0" - } - } + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "istanbul-lib-source-maps": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz", - "integrity": "sha512-UzuK0g1wyQijiaYQxj/CdNycFhAd2TLtO2obKQMTZrZ1jzEMRY3rvpASEKkaxbRR6brvdovfA03znPa/pXcejg==", - "dev": true, - "requires": { - "debug": "3.1.0", - "istanbul-lib-coverage": "1.2.0", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "source-map": "0.5.7" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "node_modules/cssstyle": { + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-5.3.7.tgz", + "integrity": "sha512-7D2EPVltRrsTkhpQmksIu+LxeWAIEk6wRDMJ1qljlv+CKHJM+cJLlfhWIzNA44eAsHXSNe3+vO6DW1yCYx8SuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@asamuzakjp/css-color": "^4.1.1", + "@csstools/css-syntax-patches-for-csstree": "^1.0.21", + "css-tree": "^3.1.0", + "lru-cache": "^11.2.4" + }, + "engines": { + "node": ">=20" } }, - "istanbul-reports": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", - "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "node_modules/cssstyle/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "requires": { - "handlebars": "4.0.11" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "jasmine": { - "version": "2.99.0", - "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.99.0.tgz", - "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=", + "node_modules/data-urls": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-6.0.1.tgz", + "integrity": "sha512-euIQENZg6x8mj3fO6o9+fOW8MimUI4PpD/fZBhJfeioZVy9TUpM4UY7KjQNVZFlqwJ0UdzRDzkycB997HEq1BQ==", "dev": true, - "requires": { - "exit": "0.1.2", - "glob": "7.1.2", - "jasmine-core": "2.99.1" - }, + "license": "MIT", "dependencies": { - "jasmine-core": { - "version": "2.99.1", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.99.1.tgz", - "integrity": "sha1-5kAN8ea1bhMLYcS80JPap/boyhU=", - "dev": true - } + "whatwg-mimetype": "^5.0.0", + "whatwg-url": "^15.1.0" + }, + "engines": { + "node": ">=20" } }, - "jasmine-core": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz", - "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=", - "dev": true - }, - "jasmine-spec-reporter": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/jasmine-spec-reporter/-/jasmine-spec-reporter-4.2.1.tgz", - "integrity": "sha512-FZBoZu7VE5nR7Nilzy+Np8KuVIOxF4oXDPDknehCYBDE080EnlPu0afdZNmpGDBRCUBv3mj5qgqCRmk6W/K8vg==", + "node_modules/data-urls/node_modules/whatwg-mimetype": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-5.0.0.tgz", + "integrity": "sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==", "dev": true, - "requires": { - "colors": "1.1.2" + "license": "MIT", + "engines": { + "node": ">=20" } }, - "jasminewd2": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz", - "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=", - "dev": true - }, - "js-base64": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", - "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true + "node_modules/decimal.js": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", + "dev": true, + "license": "MIT" }, - "js-yaml": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, - "requires": { - "argparse": "1.0.10", - "esprima": "4.0.0" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "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, - "optional": true - }, - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true + "node_modules/dexie": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/dexie/-/dexie-4.2.1.tgz", + "integrity": "sha512-Ckej0NS6jxQ4Po3OrSQBFddayRhTCic2DoCAG5zacOfOVB9P2Q5Xc5uL/nVa7ZVs+HdMnvUPzLFCB/JwpB6Csg==", + "license": "Apache-2.0" }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dev": true, - "requires": { - "jsonify": "0.0.0" + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", "dev": true, - "requires": { - "graceful-fs": "4.1.11" + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } }, - "jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", - "dev": true + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", + "node_modules/electron-to-chromium": { + "version": "1.5.267", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.267.tgz", + "integrity": "sha512-0Drusm6MVRXSOJpGbaSVgcQsuB4hEkMpHXaVstcPmhu5LIedxs1xNK/nIxmQIU/RPC0+1/o0AVZfBTkTNJOdUw==", "dev": true, - "optional": true + "license": "ISC" }, - "jsprim": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", - "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.2.3", - "verror": "1.10.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } + "license": "MIT" }, - "karma": { + "node_modules/encodeurl": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/karma/-/karma-2.0.0.tgz", - "integrity": "sha512-K9Kjp8CldLyL9ANSUctDyxC7zH3hpqXj/K09qVf06K3T/kXaHtFZ5tQciK7OzQu68FLvI89Na510kqQ2LCbpIw==", - "dev": true, - "requires": { - "bluebird": "3.5.1", - "body-parser": "1.18.2", - "browserify": "14.5.0", - "chokidar": "1.7.0", - "colors": "1.1.2", - "combine-lists": "1.0.1", - "connect": "3.6.6", - "core-js": "2.5.3", - "di": "0.0.1", - "dom-serialize": "2.2.1", - "expand-braces": "0.1.2", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "http-proxy": "1.16.2", - "isbinaryfile": "3.0.2", - "lodash": "4.17.5", - "log4js": "2.5.3", - "mime": "1.6.0", - "minimatch": "3.0.4", - "optimist": "0.6.1", - "qjobs": "1.2.0", - "range-parser": "1.2.0", - "rimraf": "2.6.2", - "safe-buffer": "5.1.1", - "socket.io": "2.0.4", - "source-map": "0.6.1", - "tmp": "0.0.33", - "useragent": "2.3.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "karma-chrome-launcher": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, - "requires": { - "fs-access": "1.0.1", - "which": "1.3.0" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "karma-coverage-istanbul-reporter": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/karma-coverage-istanbul-reporter/-/karma-coverage-istanbul-reporter-1.4.2.tgz", - "integrity": "sha512-sQHexslLF+QHzaKfK8+onTYMyvSwv+p5cDayVxhpEELGa3z0QuB+l0IMsicIkkBNMOJKQaqueiRoW7iuo7lsog==", + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", "dev": true, - "requires": { - "istanbul-api": "1.3.1", - "minimatch": "3.0.4" + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" } }, - "karma-jasmine": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-1.1.1.tgz", - "integrity": "sha1-b+hA51oRYAydkehLM8RY4cRqNSk=", - "dev": true - }, - "karma-jasmine-html-reporter": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-0.2.2.tgz", - "integrity": "sha1-SKjl7xiAdhfuK14zwRlMNbQ5Ukw=", + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", "dev": true, - "requires": { - "karma-jasmine": "1.1.1" + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "karma-source-map-support": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.2.0.tgz", - "integrity": "sha1-G/gee7SwiWJ6s1LsQXnhF8QGpUA=", + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", "dev": true, - "requires": { - "source-map-support": "0.4.18" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "killable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz", - "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", "dev": true, - "requires": { - "is-buffer": "1.1.6" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "labeled-stream-splicer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", - "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", "dev": true, - "requires": { - "inherits": "2.0.3", - "isarray": "2.0.4", - "stream-splicer": "2.0.0" + "license": "MIT", + "engines": { + "node": ">=18" }, - "dependencies": { - "isarray": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", - "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "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==", "dev": true, - "requires": { - "invert-kv": "1.0.0" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "less": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", - "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "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==", "dev": true, - "requires": { - "errno": "0.1.7", - "graceful-fs": "4.1.11", - "image-size": "0.5.5", - "mime": "1.6.0", - "mkdirp": "0.5.1", - "promise": "7.3.1", - "request": "2.81.0", - "source-map": "0.5.7" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "less-loader": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-4.1.0.tgz", - "integrity": "sha512-KNTsgCE9tMOM70+ddxp9yyt9iHqgmSs0yTZc5XH5Wo+g80RWRIYNqE58QJKm/yMud5wZEvz50ugRDuzVIkyahg==", + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", "dev": true, - "requires": { - "clone": "2.1.2", - "loader-utils": "1.1.0", - "pify": "3.0.0" - } + "license": "MIT" }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", "dev": true, - "optional": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" } }, - "lexical-scope": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", - "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", + "node_modules/esbuild": { + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", "dev": true, - "requires": { - "astw": "2.2.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "libbase64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/libbase64/-/libbase64-0.1.0.tgz", - "integrity": "sha1-YjUag5VjrF/1vSbxL2Dpgwu3UeY=", - "dev": true + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" }, - "libmime": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/libmime/-/libmime-3.0.0.tgz", - "integrity": "sha1-UaGp50SOy9Ms2lRCFnW7IbwJPaY=", + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dev": true, - "requires": { - "iconv-lite": "0.4.15", - "libbase64": "0.1.0", - "libqp": "1.1.0" - }, + "license": "MIT", "dependencies": { - "iconv-lite": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz", - "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es=", - "dev": true - } + "@types/estree": "^1.0.0" } }, - "libqp": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/libqp/-/libqp-1.1.0.tgz", - "integrity": "sha1-9ebgatdLeU+1tbZpiL9yjvHe2+g=", - "dev": true - }, - "license-webpack-plugin": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-1.3.1.tgz", - "integrity": "sha512-NqAFodJdpBUuf1iD+Ij8hQvF0rCFKlO2KaieoQzAPhFgzLCtJnC7Z7x5gQbGNjoe++wOKAtAmwVEIBLqq2Yp1A==", + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, - "requires": { - "ejs": "2.5.7" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - }, - "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", - "dev": true + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "dev": true, + "license": "MIT" }, - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", "dev": true, - "requires": { - "big.js": "3.2.0", - "emojis-list": "2.1.0", - "json5": "0.5.1" + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" + "license": "MIT", + "engines": { + "node": ">=18.0.0" } }, - "lodash": { - "version": "4.17.5", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", - "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", - "dev": true - }, - "lodash.assign": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, - "optional": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } }, - "lodash.memoize": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", - "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", - "dev": true + "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==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" + } + }, + "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" }, - "lodash.mergewith": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "node_modules/fast-uri": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "dev": true, - "optional": true + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" }, - "lodash.tail": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.tail/-/lodash.tail-4.1.1.tgz", - "integrity": "sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=", - "dev": true - }, - "log4js": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.5.3.tgz", - "integrity": "sha512-YL/qpTxYtK0iWWbuKCrevDZz5lh+OjyHHD+mICqpjnYGKdNRBvPeh/1uYjkKUemT1CSO4wwLOwphWMpKAnD9kw==", - "dev": true, - "requires": { - "amqplib": "0.5.2", - "axios": "0.15.3", - "circular-json": "0.5.1", - "date-format": "1.2.0", - "debug": "3.1.0", - "hipchat-notifier": "1.1.0", - "loggly": "1.1.1", - "mailgun-js": "0.7.15", - "nodemailer": "2.7.2", - "redis": "2.8.0", - "semver": "5.5.0", - "slack-node": "0.2.0", - "streamroller": "0.7.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" } }, - "loggly": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/loggly/-/loggly-1.1.1.tgz", - "integrity": "sha1-Cg/B0/o6XsRP3HuJe+uipGlc6+4=", + "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, - "optional": true, - "requires": { - "json-stringify-safe": "5.0.1", - "request": "2.75.0", - "timespan": "2.3.0" + "license": "MIT", + "engines": { + "node": ">=12.0.0" }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "optional": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true, - "optional": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "optional": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "form-data": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.0.0.tgz", - "integrity": "sha1-bwrrrcxdoWwT4ezBETfYX5uIOyU=", - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.6", - "mime-types": "2.1.18" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "optional": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.15.1", - "is-my-json-valid": "2.17.2", - "pinkie-promise": "2.0.1" - } - }, - "node-uuid": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/node-uuid/-/node-uuid-1.4.8.tgz", - "integrity": "sha1-sEDrCSOWivq/jTL7HxfxFn/auQc=", - "dev": true, - "optional": true - }, - "qs": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.2.3.tgz", - "integrity": "sha1-HPyyXBCpsrSDBT/zn138kjOQjP4=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.75.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.75.0.tgz", - "integrity": "sha1-0rgmiihtoT6qXQGt9dGMyQ9lfZM=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "bl": "1.1.2", - "caseless": "0.11.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.0.0", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "node-uuid": "1.4.8", - "oauth-sign": "0.8.2", - "qs": "6.2.3", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.4.3" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "optional": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { "optional": true } } }, - "loglevel": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", - "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=", - "dev": true + "node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true + "node_modules/foldline": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/foldline/-/foldline-1.1.0.tgz", + "integrity": "sha512-9SheyADS50hjvFYjFJ3OB/GlDz2mD1T2CHd7auIk4Uto5YYWPBcw8iYo3F+gENJ+/SOeH9tT0loHZSqlUlumTA==", + "license": "MIT" }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, - "requires": { - "js-tokens": "3.0.2" + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", - "dev": true - }, - "lru-cache": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.2.tgz", - "integrity": "sha512-wgeVXhrDwAWnIF/yZARsFnMBtdFXOg1b8RIrhilp+0iDYN4mdQcNZElDZ0e4B64BhaxeQ5zN7PMyvu7we1kPeQ==", + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "magic-string": { - "version": "0.22.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", - "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", + "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, - "requires": { - "vlq": "0.2.3" + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "mailcomposer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/mailcomposer/-/mailcomposer-4.0.1.tgz", - "integrity": "sha1-DhxEsqB890DuF9wUm6AJ8Zyt/rQ=", - "dev": true, - "optional": true, - "requires": { - "buildmail": "4.0.1", - "libmime": "3.0.0" - } - }, - "mailgun-js": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.7.15.tgz", - "integrity": "sha1-7jZqINrGTDwVwD1sGz4O15UlKrs=", - "dev": true, - "optional": true, - "requires": { - "async": "2.1.5", - "debug": "2.2.0", - "form-data": "2.1.4", - "inflection": "1.10.0", - "is-stream": "1.1.0", - "path-proxy": "1.0.0", - "proxy-agent": "2.0.0", - "q": "1.4.1", - "tsscmp": "1.0.5" - }, - "dependencies": { - "async": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/async/-/async-2.1.5.tgz", - "integrity": "sha1-5YfGhYCZSsZ/xW/4bTrFa9voELw=", - "dev": true, - "optional": true, - "requires": { - "lodash": "4.17.5" - } - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "optional": true, - "requires": { - "ms": "0.7.1" - } - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true, - "optional": true - } + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "make-dir": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.2.0.tgz", - "integrity": "sha512-aNUAa4UMg/UougV25bbrU4ZaaKNjJ/3/xnvg/twpmKROPdKZPZ9wGgI0opdZzO8q/zUFawoUuixuOv33eZ61Iw==", + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, - "requires": { - "pify": "3.0.0" + "license": "MIT", + "engines": { + "node": ">=6.9.0" } }, - "make-error": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.4.tgz", - "integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==", - "dev": true - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, - "requires": { - "object-visit": "1.0.1" + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" } }, - "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", + "node_modules/get-east-asian-width": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.4.0.tgz", + "integrity": "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==", "dev": true, - "requires": { - "hash-base": "3.0.4", - "inherits": "2.0.3" + "license": "MIT", + "engines": { + "node": ">=18" }, - "dependencies": { - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "dev": true, - "requires": { - "mimic-fn": "1.2.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "0.1.7", - "readable-stream": "2.3.5" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "merge-descriptors": { + "node_modules/get-proto": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.4" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", "dev": true, - "requires": { - "bn.js": "4.11.8", - "brorand": "1.1.0" + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" } }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "node_modules/glob": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-13.0.0.tgz", + "integrity": "sha512-tvZgpqk6fz4BaNZ66ZsRaZnbHvP/jG3uKJvAZOwEVUL4RTA5nJeeLYfyN9/VA8NX/V3IBG+hkeuGpKjvELkVhA==", "dev": true, - "requires": { - "mime-db": "1.33.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "minimatch": "^10.1.1", + "minipass": "^7.1.2", + "path-scurry": "^2.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "mimic-fn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", "dev": true, - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mississippi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", - "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", - "dev": true, - "requires": { - "concat-stream": "1.6.2", - "duplexify": "3.5.4", - "end-of-stream": "1.4.1", - "flush-write-stream": "1.0.3", - "from2": "2.3.0", - "parallel-transform": "1.1.0", - "pump": "2.0.1", - "pumpify": "1.4.0", - "stream-each": "1.2.2", - "through2": "2.0.3" - } - }, - "mixin-deep": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", - "dev": true, - "requires": { - "for-in": "1.0.2", - "is-extendable": "1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "2.0.4" - } - } - } + "license": "BSD-2-Clause" }, - "mixin-object": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/mixin-object/-/mixin-object-2.0.1.tgz", - "integrity": "sha1-T7lJRB2rGCVA8f4DW6YOGUel5X4=", + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", "dev": true, - "requires": { - "for-in": "0.1.8", - "is-extendable": "0.1.1" + "license": "MIT", + "engines": { + "node": ">= 0.4" }, - "dependencies": { - "for-in": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-0.1.8.tgz", - "integrity": "sha1-2Hc5COMSVhCZUrH9ubP6hn0ndeE=", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true, - "requires": { - "minimist": "0.0.8" - } + "license": "ISC" }, - "module-deps": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-4.1.1.tgz", - "integrity": "sha1-IyFYM/HaE/1gbMuAh7RIUty4If0=", - "dev": true, - "requires": { - "JSONStream": "1.3.2", - "browser-resolve": "1.11.2", - "cached-path-relative": "1.0.1", - "concat-stream": "1.5.2", - "defined": "1.0.0", - "detective": "4.7.1", - "duplexer2": "0.1.4", - "inherits": "2.0.3", - "parents": "1.0.1", - "readable-stream": "2.3.5", - "resolve": "1.6.0", - "stream-combiner2": "1.1.1", - "subarg": "1.0.0", - "through2": "2.0.3", - "xtend": "4.0.1" - }, - "dependencies": { - "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.0.6", - "typedarray": "0.0.6" - }, - "dependencies": { - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "0.10.31", - "util-deprecate": "1.0.2" - } - } - } - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", "dev": true, - "requires": { - "aproba": "1.2.0", - "copy-concurrently": "1.0.5", - "fs-write-stream-atomic": "1.0.10", - "mkdirp": "0.5.1", - "rimraf": "2.6.2", - "run-queue": "1.0.3" + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multicast-dns": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "node_modules/hono": { + "version": "4.11.4", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.4.tgz", + "integrity": "sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==", "dev": true, - "requires": { - "dns-packet": "1.3.1", - "thunky": "1.0.2" + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" } }, - "multicast-dns-service-types": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", - "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", - "dev": true - }, - "nan": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "fragment-cache": "0.2.1", - "is-odd": "2.0.0", - "is-windows": "1.0.2", - "kind-of": "6.0.2", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "ncname": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ncname/-/ncname-1.0.0.tgz", - "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "requires": { - "xml-char-classes": "1.0.0" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "negotiator": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", - "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", - "dev": true - }, - "neo-async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.0.tgz", - "integrity": "sha512-nJmSswG4As/MkRq7QZFuH/sf/yuv8ODdMZrY4Bedjp77a5MK4A6s7YbBB64c9u79EBUOfXUXBvArmvzTD0X+6g==", - "dev": true - }, - "netmask": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-1.0.6.tgz", - "integrity": "sha1-ICl+idhvb2QA8lDZ9Pa0wZRfzTU=", + "node_modules/html-encoding-sniffer": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-6.0.0.tgz", + "integrity": "sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==", "dev": true, - "optional": true - }, - "next-tick": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", - "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", - "dev": true - }, - "no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dev": true, - "requires": { - "lower-case": "1.1.4" - } - }, - "node-forge": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.1.tgz", - "integrity": "sha1-naYR6giYL0uUIGs760zJZl8gwwA=", - "dev": true - }, - "node-gyp": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", - "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "glob": "7.1.2", - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "nopt": "3.0.6", - "npmlog": "4.1.2", - "osenv": "0.1.5", - "request": "2.81.0", - "rimraf": "2.6.2", - "semver": "5.3.0", - "tar": "2.2.1", - "which": "1.3.0" - }, - "dependencies": { - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.1" - } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true, - "optional": true - } + "license": "MIT", + "dependencies": { + "@exodus/bytes": "^1.6.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" } }, - "node-libs-browser": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", - "dev": true, - "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.2.0", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.12.0", - "domain-browser": "1.2.0", - "events": "1.1.1", - "https-browserify": "1.0.0", - "os-browserify": "0.3.0", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.5", - "stream-browserify": "2.0.1", - "stream-http": "2.8.1", - "string_decoder": "1.0.3", - "timers-browserify": "2.0.6", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true + "node_modules/htmlparser2": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz", + "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" } }, - "node-modules-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/node-modules-path/-/node-modules-path-1.0.1.tgz", - "integrity": "sha1-QAlrCM560OoUaAhjr0ScfHWl0cg=", - "dev": true - }, - "node-sass": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.8.3.tgz", - "integrity": "sha512-tfFWhUsCk/Y19zarDcPo5xpj+IW3qCfOjVdHtYeG6S1CKbQOh1zqylnQK6cV3z9k80yxAnFX9Y+a9+XysDhhfg==", - "dev": true, - "optional": true, - "requires": { - "async-foreach": "0.1.3", - "chalk": "1.1.3", - "cross-spawn": "3.0.1", - "gaze": "1.1.2", - "get-stdin": "4.0.1", - "glob": "7.1.2", - "in-publish": "2.0.0", - "lodash.assign": "4.2.0", - "lodash.clonedeep": "4.5.0", - "lodash.mergewith": "4.6.1", - "meow": "3.7.0", - "mkdirp": "0.5.1", - "nan": "2.10.0", - "node-gyp": "3.6.2", - "npmlog": "4.1.2", - "request": "2.79.0", - "sass-graph": "2.2.4", - "stdout-stream": "1.4.0", - "true-case-path": "1.0.2" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "caseless": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz", - "integrity": "sha1-cVuW6phBWTzDMGeSP17GDr2k99c=", - "dev": true, - "optional": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "har-validator": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz", - "integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=", - "dev": true, - "optional": true, - "requires": { - "chalk": "1.1.3", - "commander": "2.15.1", - "is-my-json-valid": "2.17.2", - "pinkie-promise": "2.0.1" - } - }, - "qs": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz", - "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=", - "dev": true, - "optional": true - }, - "request": { - "version": "2.79.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.79.0.tgz", - "integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=", - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.11.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "2.0.6", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "qs": "6.3.2", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.4.3", - "uuid": "3.2.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "tunnel-agent": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", - "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", - "dev": true, - "optional": true - } + "node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", + "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "nodemailer": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-2.7.2.tgz", - "integrity": "sha1-8kLmSa7q45tsftdA73sGHEBNMPk=", - "dev": true, - "optional": true, - "requires": { - "libmime": "3.0.0", - "mailcomposer": "4.0.1", - "nodemailer-direct-transport": "3.3.2", - "nodemailer-shared": "1.1.0", - "nodemailer-smtp-pool": "2.8.2", - "nodemailer-smtp-transport": "2.7.2", - "socks": "1.1.9" - }, - "dependencies": { - "socks": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.9.tgz", - "integrity": "sha1-Yo1+TQSRJDVEWsC25Fk3bLPm1pE=", - "dev": true, - "optional": true, - "requires": { - "ip": "1.1.5", - "smart-buffer": "1.1.15" - } - } - } + "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==", + "dev": true, + "license": "BSD-2-Clause" }, - "nodemailer-direct-transport": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/nodemailer-direct-transport/-/nodemailer-direct-transport-3.3.2.tgz", - "integrity": "sha1-6W+vuQNYVglH5WkBfZfmBzilCoY=", + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "smtp-connection": "2.12.0" + "license": "MIT", + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "nodemailer-fetch": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/nodemailer-fetch/-/nodemailer-fetch-1.6.0.tgz", - "integrity": "sha1-ecSQihwPXzdbc/6IjamCj23JY6Q=", - "dev": true - }, - "nodemailer-shared": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/nodemailer-shared/-/nodemailer-shared-1.1.0.tgz", - "integrity": "sha1-z1mU4v0mjQD1zw+nZ6CBae2wfsA=", + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", "dev": true, - "requires": { - "nodemailer-fetch": "1.6.0" + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" } }, - "nodemailer-smtp-pool": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-pool/-/nodemailer-smtp-pool-2.8.2.tgz", - "integrity": "sha1-LrlNbPhXgLG0clzoU7nL1ejajHI=", + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" } }, - "nodemailer-smtp-transport": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/nodemailer-smtp-transport/-/nodemailer-smtp-transport-2.7.2.tgz", - "integrity": "sha1-A9ccdjFPFKx9vHvwM6am0W1n+3c=", + "node_modules/iconv-lite": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", + "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==", "dev": true, - "optional": true, - "requires": { - "nodemailer-shared": "1.1.0", - "nodemailer-wellknown": "0.1.10", - "smtp-connection": "2.12.0" + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "nodemailer-wellknown": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/nodemailer-wellknown/-/nodemailer-wellknown-0.1.10.tgz", - "integrity": "sha1-WG24EB2zDLRDjrVGc3pBqtDPE9U=", - "dev": true - }, - "nopt": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", - "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", "dev": true, - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, + "node_modules/immutable": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz", + "integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==", "dev": true, - "requires": { - "hosted-git-info": "2.6.0", - "is-builtin-module": "1.0.0", - "semver": "5.5.0", - "validate-npm-package-license": "3.0.3" - } + "license": "MIT" }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", "dev": true, - "requires": { - "remove-trailing-separator": "1.1.0" + "license": "MIT", + "engines": { + "node": ">=0.8.19" } }, - "normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", - "dev": true + "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" }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "node_modules/ini": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-6.0.0.tgz", + "integrity": "sha512-IBTdIkzZNOpqm7q3dRqJvMaldXjDHWkEDfrwGEQTs5eaQMWV+djAhR+wahyNNMAa+qpbDUhBMVt4ZKNwpPm7xQ==", "dev": true, - "requires": { - "path-key": "2.0.1" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", "dev": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" + "license": "MIT", + "engines": { + "node": ">= 12" } }, - "nth-check": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", - "integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=", + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, - "requires": { - "boolbase": "1.0.0" - } - }, - "null-check": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/null-check/-/null-check-1.0.0.tgz", - "integrity": "sha1-l33/1xdgErnsMNKjnbXPcqBDnt0=", - "dev": true - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", - "dev": true - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "0.1.1", - "define-property": "0.2.5", - "kind-of": "3.2.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - } + "license": "MIT", + "engines": { + "node": ">= 0.10" } }, - "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", "dev": true, - "requires": { - "isobject": "3.0.1" - }, + "license": "MIT", "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", + "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, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "node_modules/is-fullwidth-code-point": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", + "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==", "dev": true, - "requires": { - "isobject": "3.0.1" - }, + "license": "MIT", "dependencies": { - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "get-east-asian-width": "^1.3.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true + "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", + "optional": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } }, - "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "node_modules/is-interactive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz", + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==", "dev": true, - "requires": { - "ee-first": "1.1.1" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "on-headers": { + "node_modules/is-potential-custom-element-name": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz", - "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=", - "dev": true + "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", + "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", + "dev": true, + "license": "MIT" }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", "dev": true, - "requires": { - "wrappy": "1.0.2" - } + "license": "MIT" }, - "opn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/opn/-/opn-5.1.0.tgz", - "integrity": "sha512-iPNl7SyM8L30Rm1sjGdLLheyHVw5YXVfi3SKWJzBI7efxRwHojfRFjwE/OLM6qp9xJYMgab8WicTU1cPoY+Hpg==", + "node_modules/is-unicode-supported": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", "dev": true, - "requires": { - "is-wsl": "1.1.0" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "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/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, - "requires": { - "minimist": "0.0.8", - "wordwrap": "0.0.2" + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" } }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", "dev": true, - "optional": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - }, + "license": "BSD-3-Clause", "dependencies": { - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true, - "optional": true - } + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" } }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } }, - "original": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz", - "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=", - "dev": true, - "requires": { - "url-parse": "1.0.5" - }, - "dependencies": { - "url-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz", - "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=", - "dev": true, - "requires": { - "querystringify": "0.0.4", - "requires-port": "1.0.0" - } + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsdom": { + "version": "27.4.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-27.4.0.tgz", + "integrity": "sha512-mjzqwWRD9Y1J1KUi7W97Gja1bwOOM5Ug0EZ6UDK3xS7j7mndrkwozHtSblfomlzyB4NepioNt+B2sOSzczVgtQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@acemir/cssom": "^0.9.28", + "@asamuzakjp/dom-selector": "^6.7.6", + "@exodus/bytes": "^1.6.0", + "cssstyle": "^5.3.4", + "data-urls": "^6.0.0", + "decimal.js": "^10.6.0", + "html-encoding-sniffer": "^6.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.6", + "is-potential-custom-element-name": "^1.0.1", + "parse5": "^8.0.0", + "saxes": "^6.0.0", + "symbol-tree": "^3.2.4", + "tough-cookie": "^6.0.0", + "w3c-xmlserializer": "^5.0.0", + "webidl-conversions": "^8.0.0", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^15.1.0", + "ws": "^8.18.3", + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true } } }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", "dev": true, - "requires": { - "lcid": "1.0.0" + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" } }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "node_modules/json-parse-even-better-errors": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-5.0.0.tgz", + "integrity": "sha512-ZF1nxZ28VhQouRWhUcVlUIN3qwSgPuswK05s/HIaoetAoE/9tngVmCHjSxmSQPav1nd+lPtTL0YZ/2AFdR/iYQ==", "dev": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" + "license": "MIT", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "p-finally": { + "node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" }, - "p-limit": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "dev": true, - "requires": { - "p-try": "1.0.0" - } + "license": "BSD-2-Clause" }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, - "requires": { - "p-limit": "1.2.0" + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" } }, - "p-map": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", - "dev": true - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pac-proxy-agent": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-1.1.0.tgz", - "integrity": "sha512-QBELCWyLYPgE2Gj+4wUEiMscHrQ8nRPBzYItQNOHWavwBt25ohZHQC4qnd5IszdVVrFbLsQ+dPkm6eqdjJAmwQ==", + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", "dev": true, - "optional": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1", - "get-uri": "2.0.1", - "http-proxy-agent": "1.0.0", - "https-proxy-agent": "1.0.0", - "pac-resolver": "2.0.0", - "raw-body": "2.3.2", - "socks-proxy-agent": "2.1.1" - } + "license": "MIT" }, - "pac-resolver": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-2.0.0.tgz", - "integrity": "sha1-mbiNLxk/ve78HJpSnB8yYKtSd80=", + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", "dev": true, - "optional": true, - "requires": { - "co": "3.0.6", - "degenerator": "1.0.4", - "ip": "1.0.1", - "netmask": "1.0.6", - "thunkify": "2.1.2" - }, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { - "co": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/co/-/co-3.0.6.tgz", - "integrity": "sha1-FEXyJsXrlWE45oyawwFn6n0ua9o=", - "dev": true, - "optional": true - }, - "ip": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.0.1.tgz", - "integrity": "sha1-x+NWzeoiWucbNtcPLnGpK6TkJZA=", - "dev": true, - "optional": true - } + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" } }, - "pako": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", - "dev": true + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } }, - "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "node_modules/listr2": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz", + "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==", "dev": true, - "requires": { - "cyclist": "0.2.2", - "inherits": "2.0.3", - "readable-stream": "2.3.5" + "license": "MIT", + "dependencies": { + "cli-truncate": "^5.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" } }, - "param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "requires": { - "no-case": "2.3.2" + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parents": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", - "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, - "requires": { - "path-platform": "0.11.15" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", + "node_modules/lmdb": { + "version": "3.4.4", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.4.4.tgz", + "integrity": "sha512-+Y2DqovevLkb6DrSQ6SXTYLEd6kvlRbhsxzgJrk7BUfOVA/mt21ak6pFDZDKxiAczHMWxrb02kXBTSTIA0O94A==", "dev": true, - "requires": { - "asn1.js": "4.10.1", - "browserify-aes": "1.1.1", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.3", - "pbkdf2": "3.0.14" + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.4.4", + "@lmdb/lmdb-darwin-x64": "3.4.4", + "@lmdb/lmdb-linux-arm": "3.4.4", + "@lmdb/lmdb-linux-arm64": "3.4.4", + "@lmdb/lmdb-linux-x64": "3.4.4", + "@lmdb/lmdb-win32-arm64": "3.4.4", + "@lmdb/lmdb-win32-x64": "3.4.4" } }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", + "node_modules/log-symbols": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-7.0.1.tgz", + "integrity": "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==", "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" + "license": "MIT", + "dependencies": { + "is-unicode-supported": "^2.0.0", + "yoctocolors": "^2.1.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", "dev": true, - "requires": { - "error-ex": "1.3.1" + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", + "node_modules/log-update/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", "dev": true, - "requires": { - "better-assert": "1.0.2" + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, - "requires": { - "better-assert": "1.0.2" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "parseurl": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz", - "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-platform": { - "version": "0.11.15", - "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", - "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", - "dev": true - }, - "path-proxy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-proxy/-/path-proxy-1.0.0.tgz", - "integrity": "sha1-GOijaFn8nS8aU7SN7hOFQ8Ag3l4=", + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, - "optional": true, - "requires": { - "inflection": "1.3.8" - }, + "license": "ISC", "dependencies": { - "inflection": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.3.8.tgz", - "integrity": "sha1-y9Fg2p91sUw8xjV41POWeEvzAU4=", - "dev": true, - "optional": true - } + "yallist": "^3.0.2" } }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, - "requires": { - "pify": "3.0.0" + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" } }, - "pbkdf2": { - "version": "3.0.14", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz", - "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==", + "node_modules/make-fetch-happen": { + "version": "15.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-15.0.3.tgz", + "integrity": "sha512-iyyEpDty1mwW3dGlYXAJqC/azFn5PPvgKVwXayOGBSmKLxhKZ9fg4qIan2ePpp1vJIwfFiO34LAPZgq9SZW9Aw==", "dev": true, - "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.11" + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^4.0.0", + "cacache": "^20.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "ssri": "^13.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true + "node_modules/material-design-lite": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/material-design-lite/-/material-design-lite-1.3.0.tgz", + "integrity": "sha512-ao76b0bqSTKcEMt7Pui+J/S3eVF0b3GWfuKUwfe2lP5DKlLZOwBq37e0/bXEzxrw7/SuHAuYAdoCwY6mAYhrsg==", + "license": "Apache-2.0", + "engines": { + "node": ">=0.12.0" + } }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "node_modules/material-icons": { + "version": "1.13.14", + "resolved": "https://registry.npmjs.org/material-icons/-/material-icons-1.13.14.tgz", + "integrity": "sha512-kZOfc7xCC0rAT8Q3DQixYAeT+tBqZnxkseQtp2bxBxz7q5pMAC+wmit7vJn1g/l7wRU+HEPq23gER4iPjGs5Cg==", + "license": "Apache-2.0" }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", "dev": true, - "requires": { - "pinkie": "2.0.4" + "license": "MIT", + "engines": { + "node": ">= 0.4" } }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "node_modules/mdn-data": { + "version": "2.12.2", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.12.2.tgz", + "integrity": "sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "dev": true, - "requires": { - "find-up": "2.1.0" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "portfinder": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz", - "integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=", + "node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", "dev": true, - "requires": { - "async": "1.5.2", - "debug": "2.6.9", - "mkdirp": "0.5.1" + "license": "MIT", + "engines": { + "node": ">=18" }, - "dependencies": { - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "postcss": { - "version": "6.0.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.21.tgz", - "integrity": "sha512-y/bKfbQz2Nn/QBC08bwvYUxEFOVGfPIUOTsJ2CK5inzlXW9SdYR1x4pEsG9blRAF/PX+wRNdOah+gx/hv4q7dw==", - "dev": true, - "requires": { - "chalk": "2.3.2", - "source-map": "0.6.1", - "supports-color": "5.3.0" - }, - "dependencies": { - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "postcss-import": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-11.1.0.tgz", - "integrity": "sha512-5l327iI75POonjxkXgdRCUS+AlzAdBx4pOvMEhTKTCjb1p8IEeVR9yx3cPbmN7LIWJLbfnIXxAhoB4jpD0c/Cw==", + "node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, - "requires": { - "postcss": "6.0.21", - "postcss-value-parser": "3.3.0", - "read-cache": "1.0.0", - "resolve": "1.6.0" + "license": "MIT", + "dependencies": { + "mime-db": "^1.54.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "postcss-load-config": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-1.2.0.tgz", - "integrity": "sha1-U56a/J3chiASHr+djDZz4M5Q0oo=", + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", "dev": true, - "requires": { - "cosmiconfig": "2.2.2", - "object-assign": "4.1.1", - "postcss-load-options": "1.2.0", - "postcss-load-plugins": "2.3.0" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "postcss-load-options": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/postcss-load-options/-/postcss-load-options-1.2.0.tgz", - "integrity": "sha1-sJixVZ3awt8EvAuzdfmaXP4rbYw=", + "node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", "dev": true, - "requires": { - "cosmiconfig": "2.2.2", - "object-assign": "4.1.1" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "postcss-load-plugins": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/postcss-load-plugins/-/postcss-load-plugins-2.3.0.tgz", - "integrity": "sha1-dFdoEWWZrKLwCfrUJrABdQSdjZI=", + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", "dev": true, - "requires": { - "cosmiconfig": "2.2.2", - "object-assign": "4.1.1" + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "postcss-loader": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-2.1.3.tgz", - "integrity": "sha512-RuBcNE8rjCkIB0IsbmkGFRmQJTeQJfCI88E0VTarPNTvaNSv9OFv1DvTwgtAN/qlzyiELsmmmtX/tEzKp/cdug==", + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", "dev": true, - "requires": { - "loader-utils": "1.1.0", - "postcss": "6.0.21", - "postcss-load-config": "1.2.0", - "schema-utils": "0.4.5" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" } }, - "postcss-url": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/postcss-url/-/postcss-url-7.3.1.tgz", - "integrity": "sha512-Ya5KIjGptgz0OtrVYfi2UbLxVAZ6Emc4Of+Grx4Sf1deWlRpFwLr8FrtkUxfqh+XiZIVkXbjQrddE10ESpNmdA==", + "node_modules/minipass-fetch": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-5.0.0.tgz", + "integrity": "sha512-fiCdUALipqgPWrOVTz9fw0XhcazULXOSU6ie40DDbX1F49p1dBrSRBuswndTx1x3vEb/g0FT7vC4c4C2u/mh3A==", "dev": true, - "requires": { - "mime": "1.6.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "postcss": "6.0.21", - "xxhashjs": "0.2.2" + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" } }, - "postcss-value-parser": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "pretty-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", - "integrity": "sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=", + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", "dev": true, - "requires": { - "renderkid": "2.0.1", - "utila": "0.4.0" + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" } }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", - "dev": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "optional": true, - "requires": { - "asap": "2.0.6" + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "protractor": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.1.2.tgz", - "integrity": "sha1-myIXQXCaTGLVzVPGqt1UpxE36V8=", - "dev": true, - "requires": { - "@types/node": "6.0.103", - "@types/q": "0.0.32", - "@types/selenium-webdriver": "2.53.43", - "blocking-proxy": "0.0.5", - "chalk": "1.1.3", - "glob": "7.1.2", - "jasmine": "2.99.0", - "jasminewd2": "2.2.0", - "optimist": "0.6.1", - "q": "1.4.1", - "saucelabs": "1.3.0", - "selenium-webdriver": "3.0.1", - "source-map-support": "0.4.18", - "webdriver-js-extender": "1.0.0", - "webdriver-manager": "12.0.6" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.1", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.2" - } - }, - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "webdriver-manager": { - "version": "12.0.6", - "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.0.6.tgz", - "integrity": "sha1-PfGkgZdwELTL+MnYXHpXeCjA5ws=", - "dev": true, - "requires": { - "adm-zip": "0.4.7", - "chalk": "1.1.3", - "del": "2.2.2", - "glob": "7.1.2", - "ini": "1.3.5", - "minimist": "1.2.0", - "q": "1.4.1", - "request": "2.81.0", - "rimraf": "2.6.2", - "semver": "5.5.0", - "xml2js": "0.4.19" - } - } - } + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" }, - "proxy-addr": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", - "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", "dev": true, - "requires": { - "forwarded": "0.1.2", - "ipaddr.js": "1.6.0" + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "proxy-agent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.0.0.tgz", - "integrity": "sha1-V+tTR6qAXXTsaByyVknbo5yTNJk=", - "dev": true, - "optional": true, - "requires": { - "agent-base": "2.1.1", - "debug": "2.6.9", - "extend": "3.0.1", - "http-proxy-agent": "1.0.0", - "https-proxy-agent": "1.0.0", - "lru-cache": "2.6.5", - "pac-proxy-agent": "1.1.0", - "socks-proxy-agent": "2.1.1" - }, - "dependencies": { - "lru-cache": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz", - "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U=", - "dev": true, - "optional": true - } + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "public-encrypt": { + "node_modules/minipass-pipeline/node_modules/yallist": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true, - "requires": { - "bn.js": "4.11.8", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", - "randombytes": "2.0.6" - } + "license": "ISC" }, - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "once": "1.4.0" + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "pumpify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.4.0.tgz", - "integrity": "sha512-2kmNR9ry+Pf45opRVirpNuIFotsxUGLaYqxIwuR77AYrYRMuFCz9eryHBS52L360O+NcR383CL4QYlMKPq4zYA==", + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", "dev": true, - "requires": { - "duplexify": "3.5.4", - "inherits": "2.0.3", - "pump": "2.0.1" + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "punycode": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", - "dev": true - }, - "q": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz", - "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=", - "dev": true - }, - "qjobs": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", - "dev": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "querystringify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz", - "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=", - "dev": true - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" } }, - "randombytes": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", "dev": true, - "requires": { - "safe-buffer": "5.1.1" + "license": "MIT", + "engines": { + "node": ">=10" } }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "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, - "requires": { - "randombytes": "2.0.6", - "safe-buffer": "5.1.1" - } + "license": "MIT" }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "node_modules/msgpackr": { + "version": "1.11.8", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.8.tgz", + "integrity": "sha512-bC4UGzHhVvgDNS7kn9tV8fAucIYUBuGojcaLiz7v+P63Lmtm0Xeji8B/8tYKddALXxJLpwIeBmUN3u64C4YkRA==", "dev": true, - "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" } }, - "raw-loader": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/raw-loader/-/raw-loader-0.5.1.tgz", - "integrity": "sha1-DD0L6u2KAclm2Xh793goElKpeao=", - "dev": true - }, - "read-cache": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", - "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=", + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", "dev": true, - "requires": { - "pify": "2.3.0" - }, + "hasInstallScript": true, + "license": "MIT", + "optional": true, "dependencies": { - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" } }, - "read-only-stream": { + "node_modules/mute-stream": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", - "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", "dev": true, - "requires": { - "readable-stream": "2.3.5" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - }, - "dependencies": { - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "readable-stream": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.5.tgz", - "integrity": "sha512-tK0yDhrkygt/knjowCUiWP9YdV7c5R+8cR0r/kt9ZhBU906Fs6RpQJCEilamRJj1Nx2rWI6LkW9gKqjTkshhEw==", + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" + "license": "MIT", + "engines": { + "node": ">= 0.6" } }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.5", - "set-immediate-shim": "1.0.1" - } + "license": "MIT", + "optional": true }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "node_modules/node-gyp": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-12.1.0.tgz", + "integrity": "sha512-W+RYA8jBnhSr2vrTtlPYPc1K+CSjGpVDRZxcqJcERZ8ND3A1ThWPHRwctTx3qC3oW99jt726jhdz3Y6ky87J4g==", "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^15.0.0", + "nopt": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "tar": "^7.5.2", + "tinyglobby": "^0.2.12", + "which": "^6.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "redis": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", "dev": true, + "license": "MIT", "optional": true, - "requires": { - "double-ended-queue": "2.1.0-0", - "redis-commands": "1.3.5", - "redis-parser": "2.6.0" + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" } }, - "redis-commands": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz", - "integrity": "sha512-foGF8u6MXGFF++1TZVC6icGXuMYPftKXt1FBT2vrfU9ZATNtZJ8duRC5d1lEfE8hyVe3jhelHGB91oB7I6qLsA==", - "dev": true, - "optional": true - }, - "redis-parser": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz", - "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs=", - "dev": true, - "optional": true - }, - "reflect-metadata": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.12.tgz", - "integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A==", - "dev": true - }, - "regenerate": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz", - "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==", - "dev": true - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true - }, - "regex-cache": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "requires": { - "is-equal-shallow": "0.1.3" + "license": "ISC", + "engines": { + "node": ">=16" } }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "node_modules/node-gyp/node_modules/which": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-6.0.0.tgz", + "integrity": "sha512-f+gEpIKMR9faW/JgAgPK1D7mekkFoqbmiwvNzuhsHetni20QSgzg9Vhn0g2JSJkkfehQnqdUAx7/e15qS1lPxg==", "dev": true, - "requires": { - "extend-shallow": "3.0.2", - "safe-regex": "1.1.0" + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "regexpu-core": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", - "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "node_modules/node-releases": { + "version": "2.0.27", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz", + "integrity": "sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA==", "dev": true, - "requires": { - "regenerate": "1.3.3", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true + "license": "MIT" }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", + "node_modules/nopt": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-9.0.0.tgz", + "integrity": "sha512-Zhq3a+yFKrYwSBluL4H9XP3m3y5uvQkB/09CwDruCiRmR/UJYnn9W4R48ry0uGC70aeTPKLynBtscP9efFFcPw==", "dev": true, - "requires": { - "jsesc": "0.5.0" - }, + "license": "ISC", "dependencies": { - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - } - } - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-2.0.1.tgz", - "integrity": "sha1-iYyr/Ivt5Le5ETWj/9Mj5YwNsxk=", - "dev": true, - "requires": { - "css-select": "1.2.0", - "dom-converter": "0.1.4", - "htmlparser2": "3.3.0", - "strip-ansi": "3.0.1", - "utila": "0.3.3" - }, - "dependencies": { - "utila": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.3.3.tgz", - "integrity": "sha1-1+jn1+MJEHCSsF+NloiCTWM6QiY=", - "dev": true - } - } - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.6", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.18", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.4", - "tunnel-agent": "0.6.0", - "uuid": "3.2.1" - } - }, - "requestretry": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", - "dev": true, - "optional": true, - "requires": { - "extend": "3.0.1", - "lodash": "4.17.5", - "request": "2.81.0", - "when": "3.7.8" - }, - "dependencies": { - "when": { - "version": "3.7.8", - "resolved": "https://registry.npmjs.org/when/-/when-3.7.8.tgz", - "integrity": "sha1-xxMLan6gRpPoQs3J56Hyqjmjn4I=", - "dev": true, - "optional": true - } + "abbrev": "^4.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.6.0.tgz", - "integrity": "sha512-mw7JQNu5ExIkcw4LPih0owX/TZXjD/ZUF/ZQ/pDnkw3ZKhDcZZw5klmBlj6gVMwjQ3Pz5Jgu7F3d0jcDVuEWdw==", + "node_modules/npm-bundled": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-5.0.0.tgz", + "integrity": "sha512-JLSpbzh6UUXIEoqPsYBvVNVmyrjVZ1fzEFbqxKkTJQkWBO3xFzFT+KDnSKQWwOQNbuWRwt5LSD6HOTLGIWzfrw==", "dev": true, - "requires": { - "path-parse": "1.0.5" + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^5.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "node_modules/npm-install-checks": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-8.0.0.tgz", + "integrity": "sha512-ScAUdMpyzkbpxoNekQ3tNRdFI8SJ86wgKZSQZdUxT+bj0wVFpsEMWnkXP0twVe1gJyNF5apBWDJhhIbgrIViRA==", "dev": true, - "requires": { - "resolve-from": "3.0.0" + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", + "node_modules/npm-normalize-package-bin": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-5.0.0.tgz", + "integrity": "sha512-CJi3OS4JLsNMmr2u07OJlhcrPxCeOeP/4xq67aWNai6TNWWbTrlNDgl8NcFKVlcBKp18GPj+EzbNIgrBfZhsag==", "dev": true, - "requires": { - "align-text": "0.1.4" + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "rimraf": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "node_modules/npm-package-arg": { + "version": "13.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.2.tgz", + "integrity": "sha512-IciCE3SY3uE84Ld8WZU23gAPPV9rIYod4F+rc+vJ7h7cwAJt9Vk6TVsK60ry7Uj3SRS3bqRRIGuTp9YVlk6WNA==", "dev": true, - "requires": { - "glob": "7.1.2" + "license": "ISC", + "dependencies": { + "hosted-git-info": "^9.0.0", + "proc-log": "^6.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^7.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", + "node_modules/npm-packlist": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", + "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", "dev": true, - "requires": { - "hash-base": "2.0.2", - "inherits": "2.0.3" + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "node_modules/npm-pick-manifest": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-11.0.3.tgz", + "integrity": "sha512-buzyCfeoGY/PxKqmBqn1IUJrZnUi1VVJTdSSRPGI60tJdUhUoSQFhs0zycJokDdOznQentgrpf8LayEHyyYlqQ==", "dev": true, - "requires": { - "aproba": "1.2.0" - } - }, - "rxjs": { - "version": "5.5.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.7.tgz", - "integrity": "sha512-Hxo2ac8gRQjwjtKgukMIwBRbq5+KAeEV5hXM4obYBOAghev41bDQWgFH4svYiU9UnQ5kNww2LgfyBdevCd2HXA==", - "requires": { - "symbol-observable": "1.0.1" + "license": "ISC", + "dependencies": { + "npm-install-checks": "^8.0.0", + "npm-normalize-package-bin": "^5.0.0", + "npm-package-arg": "^13.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "node_modules/npm-registry-fetch": { + "version": "19.1.1", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-19.1.1.tgz", + "integrity": "sha512-TakBap6OM1w0H73VZVDf44iFXsOS3h+L4wVMXmbWOQroZgFhMch0juN6XSzBNlD965yIKvWg2dfu7NSiaYLxtw==", "dev": true, - "requires": { - "ret": "0.1.15" + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^4.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^15.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^5.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^13.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "sass-graph": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", - "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, - "optional": true, - "requires": { - "glob": "7.1.2", - "lodash": "4.17.5", - "scss-tokenizer": "0.2.3", - "yargs": "7.1.0" + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" } }, - "sass-loader": { - "version": "6.0.7", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-6.0.7.tgz", - "integrity": "sha512-JoiyD00Yo1o61OJsoP2s2kb19L1/Y2p3QFcCdWdF6oomBGKVYuZyqHWemRBfQ2uGYsk+CH3eCguXNfpjzlcpaA==", + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, - "requires": { - "clone-deep": "2.0.2", - "loader-utils": "1.1.0", - "lodash.tail": "4.1.1", - "neo-async": "2.5.0", - "pify": "3.0.0" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "saucelabs": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.3.0.tgz", - "integrity": "sha1-0kDoAJ33+ocwbsRXimm6O1xCT+4=", + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "dev": true, - "requires": { - "https-proxy-agent": "1.0.0" + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "sax": { - "version": "0.5.8", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.5.8.tgz", - "integrity": "sha1-1HLbIo6zMcJQaw6MFVJK25OdEsE=", - "dev": true - }, - "schema-utils": { - "version": "0.4.5", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", - "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "node_modules/obug": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.1.tgz", + "integrity": "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ==", "dev": true, - "requires": { - "ajv": "6.4.0", - "ajv-keywords": "3.1.0" - } + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT" }, - "scss-tokenizer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", - "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, - "optional": true, - "requires": { - "js-base64": "2.4.3", - "source-map": "0.4.4" - }, + "license": "MIT", "dependencies": { - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "optional": true, - "requires": { - "amdefine": "1.0.1" - } - } + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" } }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selenium-webdriver": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.0.1.tgz", - "integrity": "sha1-ot6l2kqX9mcuiefKcnbO+jZRR6c=", - "dev": true, - "requires": { - "adm-zip": "0.4.7", - "rimraf": "2.6.2", - "tmp": "0.0.30", - "xml2js": "0.4.19" - }, - "dependencies": { - "tmp": { - "version": "0.0.30", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz", - "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - } + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" } }, - "selfsigned": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.2.tgz", - "integrity": "sha1-tESVgNmZKbZbEKSDiTAaZZIIh1g=", + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", "dev": true, - "requires": { - "node-forge": "0.7.1" + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "semver": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", - "dev": true - }, - "semver-dsl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/semver-dsl/-/semver-dsl-1.0.1.tgz", - "integrity": "sha1-02eN5VVeimH2Ke7QJTZq5fJzQKA=", + "node_modules/ora": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-9.0.0.tgz", + "integrity": "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A==", "dev": true, - "requires": { - "semver": "5.5.0" + "license": "MIT", + "dependencies": { + "chalk": "^5.6.2", + "cli-cursor": "^5.0.0", + "cli-spinners": "^3.2.0", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.1.0", + "log-symbols": "^7.0.1", + "stdin-discarder": "^0.2.2", + "string-width": "^8.1.0", + "strip-ansi": "^7.1.2" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "semver-intersect": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/semver-intersect/-/semver-intersect-1.3.1.tgz", - "integrity": "sha1-j6hKnhAovSOeRTDRo+GB5pjYhLo=", - "dev": true, - "requires": { - "semver": "5.5.0" - } - }, - "send": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz", - "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==", - "dev": true, - "requires": { - "debug": "2.6.9", - "depd": "1.1.2", - "destroy": "1.0.4", - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "etag": "1.8.1", - "fresh": "0.5.2", - "http-errors": "1.6.2", - "mime": "1.4.1", - "ms": "2.0.0", - "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" - }, - "dependencies": { - "mime": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz", - "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==", - "dev": true - } - } + "node_modules/ordered-binary": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.1.tgz", + "integrity": "sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==", + "dev": true, + "license": "MIT", + "optional": true }, - "serialize-javascript": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.4.0.tgz", - "integrity": "sha1-fJWFFNtqwkQ6irwGLcn3iGp/YAU=", - "dev": true + "node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pacote": { + "version": "21.0.4", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.4.tgz", + "integrity": "sha512-RplP/pDW0NNNDh3pnaoIWYPvNenS7UqMbXyvMqJczosiFWTeGGwJC2NQBLqKf4rGLFfwCOnntw1aEp9Jiqm1MA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^7.0.0", + "@npmcli/installed-package-contents": "^4.0.0", + "@npmcli/package-json": "^7.0.0", + "@npmcli/promise-spawn": "^9.0.0", + "@npmcli/run-script": "^10.0.0", + "cacache": "^20.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^13.0.0", + "npm-packlist": "^10.0.1", + "npm-pick-manifest": "^11.0.1", + "npm-registry-fetch": "^19.0.0", + "proc-log": "^6.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^4.0.0", + "ssri": "^13.0.0", + "tar": "^7.4.3" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "node_modules/parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-8.0.0.tgz", + "integrity": "sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA==", "dev": true, - "requires": { - "accepts": "1.3.5", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "1.0.3", - "http-errors": "1.6.2", - "mime-types": "2.1.18", - "parseurl": "1.3.2" + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "serve-static": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz", - "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", + "node_modules/parse5-html-rewriting-stream": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-8.0.0.tgz", + "integrity": "sha512-wzh11mj8KKkno1pZEu+l2EVeWsuKDfR5KNWZOTsslfUX8lPDZx77m9T0kIoAVkFtD1nx6YF8oh4BnPHvxMtNMw==", "dev": true, - "requires": { - "encodeurl": "1.0.2", - "escape-html": "1.0.3", - "parseurl": "1.3.2", - "send": "0.16.2" + "license": "MIT", + "dependencies": { + "entities": "^6.0.0", + "parse5": "^8.0.0", + "parse5-sax-parser": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "set-value": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "split-string": "3.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } + "node_modules/parse5-html-rewriting-stream/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "node_modules/parse5-sax-parser": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-8.0.0.tgz", + "integrity": "sha512-/dQ8UzHZwnrzs3EvDj6IkKrD/jIZyTlB+8XrHJvcjNgRdmWruNdN9i9RK/JtxakmlUdPwKubKPTCqvbTgzGhrw==", "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" + "license": "MIT", + "dependencies": { + "parse5": "^8.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "shallow-clone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-1.0.0.tgz", - "integrity": "sha512-oeXreoKR/SyNJtRJMAKPDSvd28OqEwG4eR/xc856cRGBII7gX9lvAqDxusPm0846z/w/hWYjI1NpKwJ00NHzRA==", + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "dev": true, - "requires": { - "is-extendable": "0.1.1", - "kind-of": "5.1.0", - "mixin-object": "2.0.1" + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" } }, - "shasum": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", - "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", - "dev": true, - "requires": { - "json-stable-stringify": "0.0.1", - "sha.js": "2.4.11" - }, - "dependencies": { - "json-stable-stringify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", - "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - } + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "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, - "requires": { - "shebang-regex": "1.0.0" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" }, - "shell-quote": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", - "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "node_modules/path-scurry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.1.tgz", + "integrity": "sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==", "dev": true, - "requires": { - "array-filter": "0.0.1", - "array-map": "0.0.0", - "array-reduce": "0.0.0", - "jsonify": "0.0.0" + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "silent-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/silent-error/-/silent-error-1.1.0.tgz", - "integrity": "sha1-IglwbxyFCp8dENDYQJGLRvJuG8k=", + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", "dev": true, - "requires": { - "debug": "2.6.9" + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" } }, - "slack-node": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/slack-node/-/slack-node-0.2.0.tgz", - "integrity": "sha1-3kuN3aqLeT9h29KTgQT9q/N9+jA=", + "node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "dev": true, - "optional": true, - "requires": { - "requestretry": "1.13.0" + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "smart-buffer": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", - "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=", - "dev": true - }, - "smtp-connection": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/smtp-connection/-/smtp-connection-2.12.0.tgz", - "integrity": "sha1-1275EnyyPCJZ7bHoNJwujV4tdME=", - "dev": true, - "requires": { - "httpntlm": "1.6.1", - "nodemailer-shared": "1.1.0" - } - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "0.11.2", - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "map-cache": "0.2.2", - "source-map": "0.5.7", - "source-map-resolve": "0.5.1", - "use": "3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "1.0.0", - "isobject": "3.0.1", - "snapdragon-util": "3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } - } + "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" }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, - "requires": { - "kind-of": "3.2.2" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", + "node_modules/piscina": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-5.1.4.tgz", + "integrity": "sha512-7uU4ZnKeQq22t9AsmHGD2w4OYQGonwFnTypDypaWi7Qr2EvQIFVtG8J5D/3bE7W123Wdc9+v4CZDu5hJXVCtBg==", "dev": true, - "requires": { - "hoek": "2.16.3" + "license": "MIT", + "engines": { + "node": ">=20.x" + }, + "optionalDependencies": { + "@napi-rs/nice": "^1.0.4" } }, - "socket.io": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz", - "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "dev": true, - "requires": { - "debug": "2.6.9", - "engine.io": "3.1.5", - "socket.io-adapter": "1.1.1", - "socket.io-client": "2.0.4", - "socket.io-parser": "3.1.3" + "license": "MIT", + "engines": { + "node": ">=16.20.0" } }, - "socket.io-adapter": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz", - "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs=", - "dev": true - }, - "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.6.9", - "engine.io-client": "3.1.6", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "3.1.3", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "3.1.0", - "has-binary2": "1.0.2", - "isarray": "2.0.1" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" } }, - "sockjs": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", "dev": true, - "requires": { - "faye-websocket": "0.10.0", - "uuid": "3.2.1" - } + "license": "MIT" }, - "sockjs-client": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz", - "integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "eventsource": "0.1.6", - "faye-websocket": "0.11.1", - "inherits": "2.0.3", - "json3": "3.3.2", - "url-parse": "1.2.0" - }, - "dependencies": { - "faye-websocket": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.1.tgz", - "integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=", - "dev": true, - "requires": { - "websocket-driver": "0.7.0" - } - } + "node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "socks": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", - "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", "dev": true, - "requires": { - "ip": "1.1.5", - "smart-buffer": "1.1.15" + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" } }, - "socks-proxy-agent": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz", - "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==", + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, - "requires": { - "agent-base": "2.1.1", - "extend": "3.0.1", - "socks": "1.1.10" + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" } }, - "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", - "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "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, - "requires": { - "atob": "2.0.3", - "decode-uri-component": "0.2.0", - "resolve-url": "0.2.1", - "source-map-url": "0.4.0", - "urix": "0.1.0" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "node_modules/qs": { + "version": "6.14.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "dev": true, - "requires": { - "source-map": "0.5.7" + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } }, - "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", "dev": true, - "requires": { - "spdx-expression-parse": "3.0.0", - "spdx-license-ids": "3.0.0" + "license": "MIT", + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.10" } }, - "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", - "dev": true + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } }, - "spdx-expression-parse": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "node_modules/readdirp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-5.0.0.tgz", + "integrity": "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==", "dev": true, - "requires": { - "spdx-exceptions": "2.1.0", - "spdx-license-ids": "3.0.0" + "license": "MIT", + "engines": { + "node": ">= 20.19.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", - "dev": true - }, - "spdy": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz", - "integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=", + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", "dev": true, - "requires": { - "debug": "2.6.9", - "handle-thing": "1.2.5", - "http-deceiver": "1.2.7", - "safe-buffer": "5.1.1", - "select-hose": "2.0.0", - "spdy-transport": "2.1.0" - } + "license": "Apache-2.0" }, - "spdy-transport": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", - "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", + "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==", "dev": true, - "requires": { - "debug": "2.6.9", - "detect-node": "2.0.3", - "hpack.js": "2.1.6", - "obuf": "1.1.2", - "readable-stream": "2.3.5", - "safe-buffer": "5.1.1", - "wbuf": "1.7.3" + "license": "MIT", + "engines": { + "node": ">=0.10.0" } }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "node_modules/resolve": { + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, - "requires": { - "extend-shallow": "3.0.2" + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", - "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "ssri": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", - "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, - "requires": { - "safe-buffer": "5.1.1" + "license": "MIT", + "engines": { + "node": ">= 4" } }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rolldown": { + "version": "1.0.0-beta.58", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-beta.58.tgz", + "integrity": "sha512-v1FCjMZCan7f+xGAHBi+mqiE4MlH7I+SXEHSQSJoMOGNNB2UYtvMiejsq9YuUOiZjNeUeV/a21nSFbrUR+4ZCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.106.0", + "@rolldown/pluginutils": "1.0.0-beta.58" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.0.0-beta.58", + "@rolldown/binding-darwin-arm64": "1.0.0-beta.58", + "@rolldown/binding-darwin-x64": "1.0.0-beta.58", + "@rolldown/binding-freebsd-x64": "1.0.0-beta.58", + "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-beta.58", + "@rolldown/binding-linux-arm64-gnu": "1.0.0-beta.58", + "@rolldown/binding-linux-arm64-musl": "1.0.0-beta.58", + "@rolldown/binding-linux-x64-gnu": "1.0.0-beta.58", + "@rolldown/binding-linux-x64-musl": "1.0.0-beta.58", + "@rolldown/binding-openharmony-arm64": "1.0.0-beta.58", + "@rolldown/binding-wasm32-wasi": "1.0.0-beta.58", + "@rolldown/binding-win32-arm64-msvc": "1.0.0-beta.58", + "@rolldown/binding-win32-x64-msvc": "1.0.0-beta.58" + } + }, + "node_modules/rollup": { + "version": "4.55.3", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.3.tgz", + "integrity": "sha512-y9yUpfQvetAjiDLtNMf1hL9NXchIJgWt6zIKeoB+tCd3npX08Eqfzg60V9DhIGVMtQ0AlMkFw5xa+AQ37zxnAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.55.3", + "@rollup/rollup-android-arm64": "4.55.3", + "@rollup/rollup-darwin-arm64": "4.55.3", + "@rollup/rollup-darwin-x64": "4.55.3", + "@rollup/rollup-freebsd-arm64": "4.55.3", + "@rollup/rollup-freebsd-x64": "4.55.3", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.3", + "@rollup/rollup-linux-arm-musleabihf": "4.55.3", + "@rollup/rollup-linux-arm64-gnu": "4.55.3", + "@rollup/rollup-linux-arm64-musl": "4.55.3", + "@rollup/rollup-linux-loong64-gnu": "4.55.3", + "@rollup/rollup-linux-loong64-musl": "4.55.3", + "@rollup/rollup-linux-ppc64-gnu": "4.55.3", + "@rollup/rollup-linux-ppc64-musl": "4.55.3", + "@rollup/rollup-linux-riscv64-gnu": "4.55.3", + "@rollup/rollup-linux-riscv64-musl": "4.55.3", + "@rollup/rollup-linux-s390x-gnu": "4.55.3", + "@rollup/rollup-linux-x64-gnu": "4.55.3", + "@rollup/rollup-linux-x64-musl": "4.55.3", + "@rollup/rollup-openbsd-x64": "4.55.3", + "@rollup/rollup-openharmony-arm64": "4.55.3", + "@rollup/rollup-win32-arm64-msvc": "4.55.3", + "@rollup/rollup-win32-ia32-msvc": "4.55.3", + "@rollup/rollup-win32-x64-gnu": "4.55.3", + "@rollup/rollup-win32-x64-msvc": "4.55.3", + "fsevents": "~2.3.2" + } + }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "dev": true, - "requires": { - "define-property": "0.2.5", - "object-copy": "0.1.0" + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } + "tslib": "^2.1.0" } }, - "statuses": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==", - "dev": true + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" }, - "stdout-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", - "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, - "optional": true, - "requires": { - "readable-stream": "2.3.5" - } + "license": "MIT" }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", + "node_modules/sass": { + "version": "1.97.1", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.97.1.tgz", + "integrity": "sha512-uf6HoO8fy6ClsrShvMgaKUn14f2EHQLQRtpsZZLeU/Mv0Q1K5P0+x2uvH6Cub39TVVbWNSrraUhDAoFph6vh0A==", "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" } }, - "stream-combiner2": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", - "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "node_modules/sass/node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", "dev": true, - "requires": { - "duplexer2": "0.1.4", - "readable-stream": "2.3.5" + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" } }, - "stream-each": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", - "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "node_modules/sass/node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", "dev": true, - "requires": { - "end-of-stream": "1.4.1", - "stream-shift": "1.0.0" + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" } }, - "stream-http": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.1.tgz", - "integrity": "sha512-cQ0jo17BLca2r0GfRdZKYAGLU6JRoIWxqSOakUMuKOT6MOK7AAlE856L33QuDmAy/eeOrhLee3dZKX0Uadu93A==", + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, - "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.5", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" + "license": "ISC", + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=v12.22.7" } }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", - "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.5" - } - }, - "streamroller": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", - "dev": true, - "requires": { - "date-format": "1.2.0", - "debug": "3.1.0", - "mkdirp": "0.5.1", - "readable-stream": "2.3.5" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - } + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" } }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "node_modules/send": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" + "license": "MIT", + "dependencies": { + "debug": "^4.4.3", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.2" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "node_modules/serve-static": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "dev": true, - "requires": { - "safe-buffer": "5.1.1" + "license": "MIT", + "dependencies": { + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" + }, + "engines": { + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } + "license": "ISC" }, - "strip-bom": { + "node_modules/shebang-command": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", "dev": true, - "requires": { - "is-utf8": "0.2.1" + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "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, - "requires": { - "get-stdin": "4.0.1" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "style-loader": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz", - "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==", + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", "dev": true, - "requires": { - "loader-utils": "1.1.0", - "schema-utils": "0.3.0" - }, + "license": "MIT", "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "5.5.2" - } - } - } - }, - "stylus": { - "version": "0.54.5", - "resolved": "https://registry.npmjs.org/stylus/-/stylus-0.54.5.tgz", - "integrity": "sha1-QrlWCTHKcJDOhRWnmLqeaqPW3Hk=", - "dev": true, - "requires": { - "css-parse": "1.7.0", - "debug": "2.6.9", - "glob": "7.0.6", - "mkdirp": "0.5.1", - "sax": "0.5.8", - "source-map": "0.1.43" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "source-map": { - "version": "0.1.43", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", - "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "stylus-loader": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/stylus-loader/-/stylus-loader-3.0.2.tgz", - "integrity": "sha512-+VomPdZ6a0razP+zinir61yZgpw2NfljeSsdUF5kJuEzlo3khXhY19Fn6l8QQz1GRJGtMCo8nG5C04ePyV7SUA==", - "dev": true, - "requires": { - "loader-utils": "1.1.0", - "lodash.clonedeep": "4.5.0", - "when": "3.6.4" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "subarg": { + "node_modules/side-channel-list": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", - "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", "dev": true, - "requires": { - "minimist": "1.2.0" - }, + "license": "MIT", "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "supports-color": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", - "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", - "dev": true, - "requires": { - "has-flag": "2.0.0" + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "symbol-observable": { + "node_modules/side-channel-map": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=" - }, - "syntax-error": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", - "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", "dev": true, - "requires": { - "acorn-node": "1.3.0" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "tapable": { - "version": "0.2.8", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.8.tgz", - "integrity": "sha1-mTcqXJmb8t8WCvwNdL7U9HlIzSI=", - "dev": true - }, - "tar": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", - "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", "dev": true, - "optional": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "readable-stream": "2.3.5", - "xtend": "4.0.1" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "thunkify": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz", - "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0=", + "node_modules/sigstore": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-4.1.0.tgz", + "integrity": "sha512-/fUgUhYghuLzVT/gaJoeVehLCgZiUxPCPMcyVNY0lIf/cTCz58K/WTI7PefDarXxp9nUKpEwg1yyz3eSBMTtgA==", "dev": true, - "optional": true - }, - "thunky": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz", - "integrity": "sha1-qGLgGOP7HqLsP85dVWBc9X8kc3E=", - "dev": true - }, - "time-stamp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-2.0.0.tgz", - "integrity": "sha1-lcakRTDhW6jW9KPsuMOj+sRto1c=", - "dev": true + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^4.0.0", + "@sigstore/core": "^3.1.0", + "@sigstore/protobuf-specs": "^0.5.0", + "@sigstore/sign": "^4.1.0", + "@sigstore/tuf": "^4.0.1", + "@sigstore/verify": "^3.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "timers-browserify": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.6.tgz", - "integrity": "sha512-HQ3nbYRAowdVd0ckGFvmJPPCOH/CHleFN/Y0YQCX1DVaB7t+KFvisuyN09fuP8Jtp1CpfSh8O8bMkHbdbPe6Pw==", + "node_modules/slice-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz", + "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==", "dev": true, - "requires": { - "setimmediate": "1.0.5" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "timespan": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/timespan/-/timespan-2.3.0.tgz", - "integrity": "sha1-SQLOBAvRPYRcj1myfp1ZutbzmSk=", + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", "dev": true, - "optional": true + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } }, - "tmp": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", "dev": true, - "requires": { - "os-tmpdir": "1.0.2" + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", "dev": true, - "requires": { - "kind-of": "3.2.2" + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" } }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "node_modules/source-map": { + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, - "requires": { - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "regex-not": "1.0.2", - "safe-regex": "1.1.0" + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" } }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "3.0.0", - "repeat-string": "1.6.1" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - } + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "toposort": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toposort/-/toposort-1.0.6.tgz", - "integrity": "sha1-wxdI5V0hDv/AD9zcfW5o19e7nOw=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz", - "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", + "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==", "dev": true, - "requires": { - "punycode": "1.4.1" - }, + "license": "MIT", "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "tree-kill": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.0.tgz", - "integrity": "sha512-DlX6dR0lOIRDFxI0mjL9IYg6OTncLm/Zt+JiBhE5OlFcAR8yc9S7FFXU9so0oda47frdM/JFsk7UjNt9vscKcg==", - "dev": true - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "true-case-path": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", - "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", - "dev": true, - "optional": true, - "requires": { - "glob": "6.0.4" - }, - "dependencies": { - "glob": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", - "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", - "dev": true, - "optional": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "ts-node": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-4.1.0.tgz", - "integrity": "sha512-xcZH12oVg9PShKhy3UHyDmuDLV3y7iKwX25aMVPt1SIXSuAfWkFiGPEkg+th8R4YKW/QCxDoW7lJdb15lx6QWg==", - "dev": true, - "requires": { - "arrify": "1.0.1", - "chalk": "2.3.2", - "diff": "3.5.0", - "make-error": "1.3.4", - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map-support": "0.5.4", - "tsconfig": "7.0.0", - "v8flags": "3.0.2", - "yn": "2.0.0" - }, - "dependencies": { - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", - "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", - "dev": true, - "requires": { - "source-map": "0.6.1" - } - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, - "tsconfig": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/tsconfig/-/tsconfig-7.0.0.tgz", - "integrity": "sha512-vZXmzPrL+EmC4T/4rVlT2jNVMWCi/O4DIiSj3UHg1OE5kCKbk4mfrXc6dZksLgRM/TZlKnousKH9bbTazUWRRw==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "requires": { - "@types/strip-bom": "3.0.0", - "@types/strip-json-comments": "0.0.30", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1" - }, + "license": "Apache-2.0", "dependencies": { - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "tsickle": { - "version": "0.27.2", - "resolved": "https://registry.npmjs.org/tsickle/-/tsickle-0.27.2.tgz", - "integrity": "sha512-KW+ZgY0t2cq2Qib1sfdgMiRnk+cr3brUtzZoVWjv+Ot3jNxVorFBUH+6In6hl8Dg7BI2AAFf69NHkwvZNMSFwA==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, - "requires": { - "minimist": "1.2.0", - "mkdirp": "0.5.1", - "source-map": "0.6.1", - "source-map-support": "0.5.4" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.4.tgz", - "integrity": "sha512-PETSPG6BjY1AHs2t64vS2aqAgu6dMIMXJULWFBGbh2Gr8nVLbCFDo6i/RMMvviIQ2h1Z8+5gQhVKSn2je9nmdg==", - "dev": true, - "requires": { - "source-map": "0.6.1" - } - } - } + "license": "CC-BY-3.0" }, - "tslib": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", - "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==" - }, - "tslint": { - "version": "5.9.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.9.1.tgz", - "integrity": "sha1-ElX4ej/1frCw4fDmEKi0dIBGya4=", - "dev": true, - "requires": { - "babel-code-frame": "6.26.0", - "builtin-modules": "1.1.1", - "chalk": "2.3.2", - "commander": "2.15.1", - "diff": "3.5.0", - "glob": "7.1.2", - "js-yaml": "3.11.0", - "minimatch": "3.0.4", - "resolve": "1.6.0", - "semver": "5.5.0", - "tslib": "1.9.0", - "tsutils": "2.22.2" - }, - "dependencies": { - "chalk": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", - "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", - "dev": true, - "requires": { - "ansi-styles": "3.2.1", - "escape-string-regexp": "1.0.5", - "supports-color": "5.3.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } - } + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "tsscmp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.5.tgz", - "integrity": "sha1-fcSjOvcVgatDN9qR2FylQn69mpc=", + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", "dev": true, - "optional": true + "license": "CC0-1.0" }, - "tsutils": { - "version": "2.22.2", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.22.2.tgz", - "integrity": "sha512-u06FUSulCJ+Y8a2ftuqZN6kIGqdP2yJjUPEngXqmdPND4UQfb04igcotH+dw+IFr417yP6muCLE8/5/Qlfnx0w==", + "node_modules/ssri": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-13.0.0.tgz", + "integrity": "sha512-yizwGBpbCn4YomB2lzhZqrHLJoqFGXihNbib3ozhqF/cIp5ue+xSmOQrjNasEE62hFxsCcg/V/z23t4n8jMEng==", "dev": true, - "requires": { - "tslib": "1.9.0" + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "dev": true, - "requires": { - "safe-buffer": "5.1.1" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "node_modules/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "dev": true, - "optional": true + "license": "MIT" }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "node_modules/stdin-discarder": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.2.2.tgz", + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==", "dev": true, - "requires": { - "prelude-ls": "1.1.2" + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "type-is": { - "version": "1.6.16", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", - "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "2.1.18" + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typescript": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.5.3.tgz", - "integrity": "sha512-ptLSQs2S4QuS6/OD1eAKG+S5G8QQtrU5RT32JULdZQtM1L3WTi34Wsu48Yndzi8xsObRAB9RPt/KhA9wlpEF6w==", - "dev": true - }, - "uglify-js": { - "version": "3.3.16", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.16.tgz", - "integrity": "sha512-FMh5SRqJRGhv9BbaTffENIpDDQIoPDR8DBraunGORGhySArsXlw9++CN+BWzPBLpoI4RcSnpfGPnilTxWL3Vvg==", + "node_modules/string-width": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.1.0.tgz", + "integrity": "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg==", "dev": true, - "requires": { - "commander": "2.15.1", - "source-map": "0.6.1" - }, + "license": "MIT", "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "get-east-asian-width": "^1.3.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", + "node_modules/strip-ansi": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, - "optional": true - }, - "uglifyjs-webpack-plugin": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.4.tgz", - "integrity": "sha512-z0IbjpW8b3O/OVn+TTZN4pI29RN1zktFBXLIzzfZ+++cUtZ1ERSlLWgpE/5OERuEUs1ijVQnpYAkSlpoVmQmSQ==", - "dev": true, - "requires": { - "cacache": "10.0.4", - "find-cache-dir": "1.0.0", - "schema-utils": "0.4.5", - "serialize-javascript": "1.4.0", - "source-map": "0.6.1", - "uglify-es": "3.3.9", - "webpack-sources": "1.1.0", - "worker-farm": "1.6.0" - }, - "dependencies": { - "commander": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", - "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-es": { - "version": "3.3.9", - "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", - "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", - "dev": true, - "requires": { - "commander": "2.13.0", - "source-map": "0.6.1" - } - } + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "ultron": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", - "dev": true - }, - "umd": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", - "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", - "dev": true - }, - "underscore": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz", - "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk=", - "dev": true + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" }, - "union-value": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", - "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", - "dev": true, - "requires": { - "arr-union": "3.1.0", - "get-value": "2.0.6", - "is-extendable": "0.1.1", - "set-value": "0.4.3" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "set-value": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", - "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-extendable": "0.1.1", - "is-plain-object": "2.0.4", - "to-object-path": "0.3.0" - } - } + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "unique-filename": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", - "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "node_modules/symbol-tree": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", + "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", "dev": true, - "requires": { - "unique-slug": "2.0.0" - } + "license": "MIT" }, - "unique-slug": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", - "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "node_modules/tar": { + "version": "7.5.6", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.6.tgz", + "integrity": "sha512-xqUeu2JAIJpXyvskvU3uvQW8PAmHrtXp2KDuMJwQqW8Sqq0CaZBAQ+dKS3RBXVhU4wC5NjAdKrmh84241gO9cA==", "dev": true, - "requires": { - "imurmurhash": "0.1.4" + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", - "dev": true - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "0.3.1", - "isobject": "3.0.1" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "2.0.6", - "has-values": "0.1.4", - "isobject": "2.1.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - } + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" } }, - "upath": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.4.tgz", - "integrity": "sha512-d4SJySNBXDaQp+DPrziv3xGS6w3d2Xt69FijJr86zMPBy23JEloMCEOUBBzuN7xCtjLCnmB9tI/z7SBCahHBOw==", - "dev": true - }, - "upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", - "dev": true + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" }, - "uri-js": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", - "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "node_modules/tinyexec": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.0.2.tgz", + "integrity": "sha512-W/KYk+NFhkmsYpuHq5JykngiOCnxeVL8v8dFnqxSD8qEEdRfXk1SDM6JzNqcERbcGYj9tMrDQBYV9cjgnunFIg==", "dev": true, - "requires": { - "punycode": "2.1.0" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "node_modules/tinyglobby": { + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz", + "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==", "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, + "license": "MIT", "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" } }, - "url-loader": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz", - "integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==", + "node_modules/tinyrainbow": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.0.3.tgz", + "integrity": "sha512-PSkbLUoxOFRzJYjjxHJt9xro7D+iilgMX/C9lawzVuYiIdcihh9DXmVibBe8lmcFrRi/VzlPjBxbN7rH24q8/Q==", "dev": true, - "requires": { - "loader-utils": "1.1.0", - "mime": "1.6.0", - "schema-utils": "0.3.0" - }, - "dependencies": { - "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.1.0", - "fast-json-stable-stringify": "2.0.0", - "json-schema-traverse": "0.3.1" - } - }, - "schema-utils": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz", - "integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=", - "dev": true, - "requires": { - "ajv": "5.5.2" - } - } + "license": "MIT", + "engines": { + "node": ">=14.0.0" } }, - "url-parse": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.2.0.tgz", - "integrity": "sha512-DT1XbYAfmQP65M/mE6OALxmXzZ/z1+e5zk2TcSKe/KiYbNGZxgtttzC0mR/sjopbpOXcbniq7eIKmocJnUWlEw==", + "node_modules/tldts": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz", + "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", "dev": true, - "requires": { - "querystringify": "1.0.0", - "requires-port": "1.0.0" - }, + "license": "MIT", "dependencies": { - "querystringify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz", - "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=", - "dev": true - } + "tldts-core": "^7.0.19" + }, + "bin": { + "tldts": "bin/cli.js" } }, - "use": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "node_modules/tldts-core": { + "version": "7.0.19", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz", + "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", "dev": true, - "requires": { - "kind-of": "6.0.2" - }, - "dependencies": { - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - } - } + "license": "MIT" }, - "useragent": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/useragent/-/useragent-2.3.0.tgz", - "integrity": "sha512-4AoH4pxuSvHCjqLO04sU6U/uE65BYza8l/KKBS0b0hnUPWi+cQ2BpeTEwejCSx9SPV5/U03nniDTrWx5NrmKdw==", + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, - "requires": { - "lru-cache": "4.1.2", - "tmp": "0.0.33" + "license": "MIT", + "engines": { + "node": ">=0.6" } }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "node_modules/tough-cookie": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", + "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", "dev": true, - "requires": { - "inherits": "2.0.1" - }, + "license": "BSD-3-Clause", "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } + "tldts": "^7.0.5" + }, + "engines": { + "node": ">=16" } }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true + "node_modules/tr46": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-6.0.0.tgz", + "integrity": "sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=20" + } }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" }, - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true + "node_modules/tuf-js": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-4.1.0.tgz", + "integrity": "sha512-50QV99kCKH5P/Vs4E2Gzp7BopNV+KzTXqWeaxrfu5IQJBOULRsTIS9seSsOVT8ZnGXzCyx55nYWAi4qJzpZKEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "4.1.0", + "debug": "^4.4.3", + "make-fetch-happen": "^15.0.1" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "uws": { - "version": "9.14.0", - "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, - "optional": true + "license": "MIT", + "dependencies": { + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" + }, + "engines": { + "node": ">= 0.6" + } }, - "v8flags": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.0.2.tgz", - "integrity": "sha512-6sgSKoFw1UpUPd3cFdF7QGnrH6tDeBgW1F3v9gy8gLY0mlbiBXq8soy8aQpY6xeeCjH5K+JvC62Acp7gtl7wWA==", + "node_modules/typescript": { + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, - "requires": { - "homedir-polyfill": "1.0.1" + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" } }, - "validate-npm-package-license": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "node_modules/undici": { + "version": "7.18.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-7.18.0.tgz", + "integrity": "sha512-CfPufgPFHCYu0W4h1NiKW9+tNJ39o3kWm7Cm29ET1enSJx+AERfz7A2wAr26aY0SZbYzZlTBQtcHy15o60VZfQ==", "dev": true, - "requires": { - "spdx-correct": "3.0.0", - "spdx-expression-parse": "3.0.0" + "license": "MIT", + "engines": { + "node": ">=20.18.1" } }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true + "node_modules/undici-types": { + "version": "7.16.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.16.0.tgz", + "integrity": "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==", + "dev": true, + "license": "MIT" }, - "verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "node_modules/unique-filename": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-5.0.0.tgz", + "integrity": "sha512-2RaJTAvAb4owyjllTfXzFClJ7WsGxlykkPvCr9pA//LD9goVq+m4PPAeBgNodGZ7nSrntT/auWpJ6Y5IFXcfjg==", "dev": true, - "requires": { - "assert-plus": "1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "1.3.0" - }, + "license": "ISC", "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } + "unique-slug": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "vlq": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/vlq/-/vlq-0.2.3.tgz", - "integrity": "sha512-DRibZL6DsNhIgYQ+wNdWDL2SL3bKPlVrRiBqV5yuMm++op8W4kGFtaQfCs4KEJn0wBZcHVHJ3eoywX8983k1ow==", - "dev": true + "node_modules/unique-slug": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-6.0.0.tgz", + "integrity": "sha512-4Lup7Ezn8W3d52/xBhZBVdx323ckxa7DEvd9kPQHppTkLoJXw6ltrBCyj5pnrxj0qKDxYMJ56CoxNuFCscdTiw==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, - "requires": { - "indexof": "0.0.1" + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "void-elements": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", - "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=", - "dev": true - }, - "watchpack": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.5.0.tgz", - "integrity": "sha512-RSlipNQB1u48cq0wH/BNfCu1tD/cJ8ydFIkNYhp9o+3d+8unClkIovpW5qpFPgmL9OE48wfAnlZydXByWP82AA==", - "dev": true, - "requires": { - "chokidar": "2.0.3", - "graceful-fs": "4.1.11", - "neo-async": "2.5.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", - "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "kind-of": "6.0.2", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "chokidar": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.1", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.4" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "node_modules/update-browserslist-db": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", + "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.1", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - } + { + "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" } }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "1.0.0" - } + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" }, - "webdriver-js-extender": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz", - "integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=", + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { - "@types/selenium-webdriver": "2.53.43", - "selenium-webdriver": "2.53.3" - }, + "license": "Apache-2.0", "dependencies": { - "adm-zip": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz", - "integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=", - "dev": true - }, - "sax": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz", - "integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=", - "dev": true - }, - "selenium-webdriver": { - "version": "2.53.3", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz", - "integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=", - "dev": true, - "requires": { - "adm-zip": "0.4.4", - "rimraf": "2.6.2", - "tmp": "0.0.24", - "ws": "1.1.5", - "xml2js": "0.4.4" - } - }, - "tmp": { - "version": "0.0.24", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz", - "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=", - "dev": true - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "ws": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.5.tgz", - "integrity": "sha512-o3KqipXNUdS7wpQzBHSe180lBGO60SoK0yVo3CYJgb2MkobuWuBX6dhkYP5ORCLd55y+SaflMOV5fqAB53ux4w==", - "dev": true, - "requires": { - "options": "0.0.6", - "ultron": "1.0.2" - } - }, - "xml2js": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz", - "integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=", - "dev": true, - "requires": { - "sax": "0.6.1", - "xmlbuilder": "9.0.7" - } - } + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" } }, - "webpack": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.11.0.tgz", - "integrity": "sha512-3kOFejWqj5ISpJk4Qj/V7w98h9Vl52wak3CLiw/cDOfbVTq7FeoZ0SdoHHY9PYlHr50ZS42OfvzE2vB4nncKQg==", - "dev": true, - "requires": { - "acorn": "5.5.3", - "acorn-dynamic-import": "2.0.2", - "ajv": "6.4.0", - "ajv-keywords": "3.1.0", - "async": "2.6.0", - "enhanced-resolve": "3.4.1", - "escope": "3.6.0", - "interpret": "1.1.0", - "json-loader": "0.5.7", - "json5": "0.5.1", - "loader-runner": "2.3.0", - "loader-utils": "1.1.0", - "memory-fs": "0.4.1", - "mkdirp": "0.5.1", - "node-libs-browser": "2.1.0", - "source-map": "0.5.7", - "supports-color": "4.5.0", - "tapable": "0.2.8", - "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.5.0", - "webpack-sources": "1.1.0", - "yargs": "8.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - } - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "0.5.7", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } - } - }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", - "dev": true, - "requires": { - "source-map": "0.5.7", - "uglify-js": "2.8.29", - "webpack-sources": "1.1.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - } - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - } + "node_modules/validate-npm-package-name": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-7.0.2.tgz", + "integrity": "sha512-hVDIBwsRruT73PbK7uP5ebUt+ezEtCmzZz3F59BSr2F6OVFnJ/6h8liuvdLrQ88Xmnk6/+xGGuq+pG9WwTuy3A==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" } }, - "webpack-core": { - "version": "0.6.9", - "resolved": "https://registry.npmjs.org/webpack-core/-/webpack-core-0.6.9.tgz", - "integrity": "sha1-/FcViMhVjad76e+23r3Fo7FyvcI=", + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, - "requires": { - "source-list-map": "0.1.8", - "source-map": "0.4.4" - }, - "dependencies": { - "source-list-map": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz", - "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=", - "dev": true - }, - "source-map": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", - "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", - "dev": true, - "requires": { - "amdefine": "1.0.1" - } - } + "license": "MIT", + "engines": { + "node": ">= 0.8" } }, - "webpack-dev-middleware": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", - "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", - "dev": true, - "requires": { - "memory-fs": "0.4.1", - "mime": "1.6.0", - "path-is-absolute": "1.0.1", - "range-parser": "1.2.0", - "time-stamp": "2.0.0" - } - }, - "webpack-dev-server": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz", - "integrity": "sha512-zrPoX97bx47vZiAXfDrkw8pe9QjJ+lunQl3dypojyWwWr1M5I2h0VSrMPfTjopHQPRNn+NqfjcMmhoLcUJe2gA==", - "dev": true, - "requires": { - "ansi-html": "0.0.7", - "array-includes": "3.0.3", - "bonjour": "3.5.0", - "chokidar": "2.0.3", - "compression": "1.7.2", - "connect-history-api-fallback": "1.5.0", - "debug": "3.1.0", - "del": "3.0.0", - "express": "4.16.3", - "html-entities": "1.2.1", - "http-proxy-middleware": "0.17.4", - "import-local": "1.0.0", - "internal-ip": "1.2.0", - "ip": "1.1.5", - "killable": "1.0.0", - "loglevel": "1.6.1", - "opn": "5.1.0", - "portfinder": "1.0.13", - "selfsigned": "1.10.2", - "serve-index": "1.9.1", - "sockjs": "0.3.19", - "sockjs-client": "1.1.4", - "spdy": "3.4.7", - "strip-ansi": "3.0.1", - "supports-color": "5.3.0", - "webpack-dev-middleware": "1.12.2", - "yargs": "6.6.0" - }, - "dependencies": { - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "3.1.10", - "normalize-path": "2.1.1" - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "braces": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.1.tgz", - "integrity": "sha512-SO5lYHA3vO6gz66erVvedSCkp7AKWdv6VcQ2N4ysXfPxdAlxAMMAdwegGGcv1Bqwm7naF1hNdk5d6AAIEHV2nQ==", - "dev": true, - "requires": { - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "define-property": "1.0.0", - "extend-shallow": "2.0.1", - "fill-range": "4.0.0", - "isobject": "3.0.1", - "kind-of": "6.0.2", - "repeat-element": "1.1.2", - "snapdragon": "0.8.2", - "snapdragon-node": "2.1.1", - "split-string": "3.1.0", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } - }, - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true - }, - "chokidar": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", - "dev": true, - "requires": { - "anymatch": "2.0.0", - "async-each": "1.0.1", - "braces": "2.3.1", - "fsevents": "1.1.3", - "glob-parent": "3.1.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "4.0.0", - "normalize-path": "2.1.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0", - "upath": "1.0.4" - } + "node_modules/vcf": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/vcf/-/vcf-2.1.2.tgz", + "integrity": "sha512-oLYtZ+GJPjpKS950fw70+HavdP7ZO2Q+xMCMeCyiUKuXkJJJG1/wUjCKTagPryS1gApYjZOWW/khmdLsch8jxg==", + "license": "MIT", + "dependencies": { + "camelcase": "^5.0.0", + "foldline": "^1.1.0" + } + }, + "node_modules/vite": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.0.tgz", + "integrity": "sha512-dZwN5L1VlUBewiP6H9s2+B3e3Jg96D0vzN+Ry73sOefebhYr9f94wwkMNN/9ouoU8pV1BqA1d1zGk8928cx0rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.27.0", + "fdir": "^6.5.0", + "picomatch": "^4.0.3", + "postcss": "^8.5.6", + "rollup": "^4.43.0", + "tinyglobby": "^0.2.15" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "lightningcss": "^1.21.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "jiti": { + "optional": true }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "2.6.9", - "define-property": "0.2.5", - "extend-shallow": "2.0.1", - "posix-character-classes": "0.1.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "0.1.6" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "0.1.6", - "is-data-descriptor": "0.1.4", - "kind-of": "5.1.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } + "less": { + "optional": true }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "0.3.2", - "define-property": "1.0.0", - "expand-brackets": "2.1.4", - "extend-shallow": "2.0.1", - "fragment-cache": "0.2.1", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "1.0.2" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } + "lightningcss": { + "optional": true }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "2.0.1", - "is-number": "3.0.0", - "repeat-string": "1.6.1", - "to-regex-range": "2.1.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "0.1.1" - } - } - } + "sass": { + "optional": true }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "3.1.0", - "path-dirname": "1.0.2" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } - } - } + "sass-embedded": { + "optional": true }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "stylus": { + "optional": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } + "sugarss": { + "optional": true }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } + "terser": { + "optional": true }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "tsx": { + "optional": true }, - "is-glob": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", - "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", - "dev": true, - "requires": { - "is-extglob": "2.1.1" - } + "yaml": { + "optional": true + } + } + }, + "node_modules/vitest": { + "version": "4.0.17", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.0.17.tgz", + "integrity": "sha512-FQMeF0DJdWY0iOnbv466n/0BudNdKj1l5jYgl5JVTwjSsZSlqyXFt/9+1sEyhR6CLowbZpV7O1sCHrzBhucKKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.0.17", + "@vitest/mocker": "4.0.17", + "@vitest/pretty-format": "4.0.17", + "@vitest/runner": "4.0.17", + "@vitest/snapshot": "4.0.17", + "@vitest/spy": "4.0.17", + "@vitest/utils": "4.0.17", + "es-module-lexer": "^1.7.0", + "expect-type": "^1.2.2", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^3.10.0", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.0.3", + "vite": "^6.0.0 || ^7.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.0.17", + "@vitest/browser-preview": "4.0.17", + "@vitest/browser-webdriverio": "4.0.17", + "@vitest/ui": "4.0.17", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.6" - } - } - } + "@opentelemetry/api": { + "optional": true }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true + "@types/node": { + "optional": true }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true + "@vitest/browser-playwright": { + "optional": true }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "4.0.0", - "array-unique": "0.3.2", - "braces": "2.3.1", - "define-property": "2.0.2", - "extend-shallow": "3.0.2", - "extglob": "2.0.4", - "fragment-cache": "0.2.1", - "kind-of": "6.0.2", - "nanomatch": "1.2.9", - "object.pick": "1.3.0", - "regex-not": "1.0.2", - "snapdragon": "0.8.2", - "to-regex": "3.0.2" - } + "@vitest/browser-preview": { + "optional": true }, - "supports-color": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", - "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", - "dev": true, - "requires": { - "has-flag": "3.0.0" - } + "@vitest/browser-webdriverio": { + "optional": true }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "@vitest/ui": { + "optional": true }, - "yargs": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", - "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", - "dev": true, - "requires": { - "camelcase": "3.0.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "y18n": "3.2.1", - "yargs-parser": "4.2.1" - } + "happy-dom": { + "optional": true }, - "yargs-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", - "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", - "dev": true, - "requires": { - "camelcase": "3.0.0" - } + "jsdom": { + "optional": true } } }, - "webpack-merge": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.2.tgz", - "integrity": "sha512-/0QYwW/H1N/CdXYA2PNPVbsxO3u2Fpz34vs72xm03SRfg6bMNGfMJIQEpQjKRvkG2JvT6oRJFpDtSrwbX8Jzvw==", + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, - "requires": { - "lodash": "4.17.5" + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "webpack-sources": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "node_modules/watchpack": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz", + "integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==", "dev": true, - "requires": { - "source-list-map": "2.0.0", - "source-map": "0.6.1" - }, + "license": "MIT", "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" } }, - "webpack-subresource-integrity": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-1.0.4.tgz", - "integrity": "sha1-j6yKfo61n8ahZ2ioXJ2U7n+dDts=", + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webidl-conversions": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-8.0.1.tgz", + "integrity": "sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==", "dev": true, - "requires": { - "webpack-core": "0.6.9" + "license": "BSD-2-Clause", + "engines": { + "node": ">=20" } }, - "websocket-driver": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.0.tgz", - "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", "dev": true, - "requires": { - "http-parser-js": "0.4.11", - "websocket-extensions": "0.1.3" + "license": "MIT", + "engines": { + "node": ">=18" } }, - "websocket-extensions": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", - "dev": true + "node_modules/whatwg-url": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-15.1.0.tgz", + "integrity": "sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^6.0.0", + "webidl-conversions": "^8.0.0" + }, + "engines": { + "node": ">=20" + } }, - "when": { - "version": "3.6.4", - "resolved": "https://registry.npmjs.org/when/-/when-3.6.4.tgz", - "integrity": "sha1-RztRfsFZ4rhQBUl6E5g/CVQS404=", - "dev": true + "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" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", "dev": true, - "requires": { - "isexe": "2.0.0" + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" } }, - "which-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } }, - "wide-align": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dev": true, - "requires": { - "string-width": "1.0.2" + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" }, - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "worker-farm": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", - "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { - "errno": "0.1.7" + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "ws": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true, - "requires": { - "async-limiter": "1.0.0", - "safe-buffer": "5.1.1", - "ultron": "1.1.1" - } + "license": "ISC" }, - "xml-char-classes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/xml-char-classes/-/xml-char-classes-1.0.0.tgz", - "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=", - "dev": true - }, - "xml2js": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", "dev": true, - "requires": { - "sax": "1.2.4", - "xmlbuilder": "9.0.7" + "license": "MIT", + "engines": { + "node": ">=10.0.0" }, - "dependencies": { - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true } } }, - "xmlbuilder": { - "version": "9.0.7", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", - "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", - "dev": true + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } }, - "xmlhttprequest-ssl": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz", - "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4=", - "dev": true + "node_modules/xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true, + "license": "MIT" }, - "xregexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", - "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=", + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "dev": true, - "optional": true + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" }, - "xxhashjs": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/xxhashjs/-/xxhashjs-0.2.2.tgz", - "integrity": "sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==", + "node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "dev": true, - "requires": { - "cuint": "0.2.2" + "license": "MIT", + "dependencies": { + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true + "node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "yallist": { + "node_modules/yoctocolors": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", - "dev": true, - "optional": true, - "requires": { - "camelcase": "3.0.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "1.4.0", - "read-pkg-up": "1.0.1", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "1.0.2", - "which-module": "1.0.0", - "y18n": "3.2.1", - "yargs-parser": "5.0.0" - }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "optional": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true, - "optional": true - } + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.2.tgz", + "integrity": "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", "dev": true, - "optional": true, - "requires": { - "camelcase": "3.0.0" + "license": "MIT", + "engines": { + "node": ">=18" }, - "dependencies": { - "camelcase": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true, - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true + "node_modules/zod": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.5.tgz", + "integrity": "sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } }, - "yn": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/yn/-/yn-2.0.0.tgz", - "integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=", - "dev": true - }, - "zone.js": { - "version": "0.8.20", - "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.8.20.tgz", - "integrity": "sha512-FXlA37ErSXCMy5RNBcGFgCI/Zivqzr0D19GuvDxhcYIJc7xkFp6c29DKyODJu0Zo+EMyur/WPPgcBh1EHjB9jA==" + "node_modules/zod-to-json-schema": { + "version": "3.25.1", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } } } } diff --git a/package.json b/package.json index cf61bd4..9b1380f 100644 --- a/package.json +++ b/package.json @@ -1,52 +1,58 @@ { - "name": "sms-back-reader-2", - "version": "0.2.0", + "name": "sms-backup-viewer", + "version": "0.26.0", "license": "MIT", "scripts": { "ng": "ng", + "prestart": "node scripts/update-version.mjs", "start": "ng serve", - "build": "ng build --prod", - "test": "ng test", - "lint": "ng lint", - "e2e": "ng e2e" + "prestart:tauri": "node scripts/update-version.mjs", + "start:tauri": "ng serve --configuration tauriDev", + "start:prod": "ng serve --configuration production", + "prebuild": "node scripts/update-version.mjs", + "build": "ng build", + "prebuild:tauri": "node scripts/update-version.mjs", + "build:tauri": "ng build --configuration tauri", + "watch": "ng build --watch --configuration development", + "preview:dist": "npx http-server dist/sms-backup-viewer/browser -p 8080 -c-1", + "tauri": "tauri", + "tauri:check": "node scripts/tauri-check.mjs", + "tauri:dev": "tauri dev", + "tauri:build": "tauri build", + "test": "ng test --watch=false", + "test:watch": "ng test" }, "private": true, "dependencies": { - "@angular/animations": "^5.2.0", - "@angular/common": "^5.2.0", - "@angular/compiler": "^5.2.0", - "@angular/core": "^5.2.0", - "@angular/forms": "^5.2.0", - "@angular/http": "^5.2.0", - "@angular/platform-browser": "^5.2.0", - "@angular/platform-browser-dynamic": "^5.2.0", - "@angular/router": "^5.2.0", + "@angular/animations": "~21.1.0", + "@angular/common": "~21.1.0", + "@angular/compiler": "~21.1.0", + "@angular/core": "~21.1.0", + "@angular/forms": "~21.1.0", + "@angular/platform-browser": "~21.1.0", + "@angular/router": "~21.1.0", + "@tauri-apps/api": "^2.8.0", + "@tauri-apps/plugin-dialog": "^2.6.0", + "@tauri-apps/plugin-fs": "^2.4.5", "awesome-phonenumber": "^2.2.5", - "core-js": "^2.4.1", - "rxjs": "^5.5.6", - "ts-helpers": "^1.1.1", - "url-search-params": "^0.10.0", - "vcf": "^2.0.1", - "zone.js": "^0.8.19" + "dexie": "^4.2.1", + "fast-xml-parser": "^4.2.4", + "jszip": "^3.10.1", + "material-design-lite": "^1.3.0", + "material-icons": "^1.13.14", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "vcf": "^2.0.1" }, "devDependencies": { - "@angular/cli": "~1.7.3", - "@angular/compiler-cli": "^5.2.0", - "@angular/language-service": "^5.2.0", - "@types/jasmine": "~2.8.3", - "@types/jasminewd2": "~2.0.2", - "@types/node": "~6.0.60", - "codelyzer": "^4.0.1", - "jasmine-core": "~2.8.0", - "jasmine-spec-reporter": "~4.2.1", - "karma": "~2.0.0", - "karma-chrome-launcher": "~2.2.0", - "karma-coverage-istanbul-reporter": "^1.2.1", - "karma-jasmine": "~1.1.0", - "karma-jasmine-html-reporter": "^0.2.2", - "protractor": "~5.1.2", - "ts-node": "~4.1.0", - "tslint": "~5.9.1", - "typescript": "~2.5.3" + "@angular/build": "~21.1.0", + "@angular/cdk": "~21.1.0", + "@angular/cli": "~21.1.0", + "@angular/compiler-cli": "~21.1.0", + "@tauri-apps/cli": "^2.9.6", + "@types/node": "^24.0.0", + "jsdom": "^27.1.0", + "typescript": "~5.9.2", + "vitest": "^4.0.8" } } diff --git a/protractor.conf.js b/protractor.conf.js deleted file mode 100644 index 7ee3b5e..0000000 --- a/protractor.conf.js +++ /dev/null @@ -1,28 +0,0 @@ -// Protractor configuration file, see link for more information -// https://github.com/angular/protractor/blob/master/lib/config.ts - -const { SpecReporter } = require('jasmine-spec-reporter'); - -exports.config = { - allScriptsTimeout: 11000, - specs: [ - './e2e/**/*.e2e-spec.ts' - ], - capabilities: { - 'browserName': 'chrome' - }, - directConnect: true, - baseUrl: 'http://localhost:4200/', - framework: 'jasmine', - jasmineNodeOpts: { - showColors: true, - defaultTimeoutInterval: 30000, - print: function() {} - }, - onPrepare() { - require('ts-node').register({ - project: 'e2e/tsconfig.e2e.json' - }); - jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } })); - } -}; diff --git a/scripts/tauri-check.mjs b/scripts/tauri-check.mjs new file mode 100644 index 0000000..ecf9267 --- /dev/null +++ b/scripts/tauri-check.mjs @@ -0,0 +1,39 @@ +import { spawnSync } from 'node:child_process'; + +function commandExists(cmd) { + const isWin = process.platform === 'win32'; + const which = isWin ? 'where' : 'which'; + const res = spawnSync(which, [cmd], { stdio: 'ignore', shell: true }); + return res.status === 0; +} + +function runVersion(cmd) { + const res = spawnSync(cmd, ['--version'], { encoding: 'utf8', shell: true }); + if (res.status !== 0) { + return null; + } + return (res.stdout || '').trim(); +} + +const missing = []; +if (!commandExists('cargo')) missing.push('cargo'); +if (!commandExists('rustc')) missing.push('rustc'); + +if (missing.length) { + console.error(`Missing required tool(s): ${missing.join(', ')}`); + console.error('Tauri requires Rust (cargo + rustc). Install via https://rustup.rs/ and reopen your terminal.'); + process.exit(1); +} + +const cargoVer = runVersion('cargo'); +const rustcVer = runVersion('rustc'); + +console.log('Tauri preflight OK'); +if (cargoVer) console.log(`- ${cargoVer}`); +if (rustcVer) console.log(`- ${rustcVer}`); + +if (process.platform === 'win32') { + console.log('Windows notes:'); + console.log('- Ensure Visual Studio Build Tools (Desktop development with C++) is installed.'); + console.log('- Ensure WebView2 Runtime is installed (often already on Win10/11).'); +} diff --git a/scripts/update-version.mjs b/scripts/update-version.mjs new file mode 100644 index 0000000..cf9f783 --- /dev/null +++ b/scripts/update-version.mjs @@ -0,0 +1,67 @@ +import fs from 'fs'; +import path from 'path'; +import { fileURLToPath } from 'url'; +import { spawnSync } from 'child_process'; + +const __dirname = path.dirname(fileURLToPath(import.meta.url)); +const repoRoot = path.resolve(__dirname, '..'); +const pkgPath = path.join(repoRoot, 'package.json'); +const versionFile = path.join(repoRoot, 'src', 'app', 'version.ts'); + +function readPackageVersion() { + try { + const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); + return pkg.version || '0.0.0'; + } catch (e) { + console.error('Failed to read package.json for version:', e); + return '0.0.0'; + } +} + +function getGitCommitShort() { + try { + const res = spawnSync('git', ['rev-parse', '--short', 'HEAD'], { encoding: 'utf8' }); + if (res.status === 0 && res.stdout) { + return (res.stdout || '').trim(); + } + return null; + } catch (e) { + return null; + } +} + +function buildVersionFile(version, buildTimeIso, commit) { + const commitLine = commit ? `export const APP_GIT_COMMIT = '${commit}';\n` : ''; + return `// This file is auto-generated by scripts/update-version.mjs +// Do not edit manually - changes will be overwritten at build time. +export const APP_VERSION = '${version}'; +export const APP_BUILD_TIME = '${buildTimeIso}'; +${commitLine}`; +} + +function writeIfChanged(filePath, content) { + try { + // Ensure target directory exists + const dir = path.dirname(filePath); + if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true }); + + if (fs.existsSync(filePath)) { + const existing = fs.readFileSync(filePath, 'utf8'); + if (existing === content) { + console.log('Version file up-to-date:', filePath); + return; + } + } + fs.writeFileSync(filePath, content, 'utf8'); + console.log('Wrote version file:', filePath); + } catch (e) { + console.error('Failed to write version file:', e); + process.exit(1); + } +} + +const version = readPackageVersion(); +const buildTime = new Date().toISOString(); +const commit = getGitCommitShort(); +const content = buildVersionFile(version, buildTime, commit); +writeIfChanged(versionFile, content); diff --git a/src-tauri/.gitignore b/src-tauri/.gitignore new file mode 100644 index 0000000..502406b --- /dev/null +++ b/src-tauri/.gitignore @@ -0,0 +1,4 @@ +# Generated by Cargo +# will have compiled files and executables +/target/ +/gen/schemas diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock new file mode 100644 index 0000000..e640b2a --- /dev/null +++ b/src-tauri/Cargo.lock @@ -0,0 +1,5030 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom 0.2.17", + "once_cell", + "version_check", +] + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "android_log-sys" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84521a3cf562bc62942e294181d9eef17eb38ceb8c68677bc49f144e4c3d4f8d" + +[[package]] +name = "android_logger" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbb4e440d04be07da1f1bf44fb4495ebd58669372fe0cffa6e48595ac5bd88a3" +dependencies = [ + "android_log-sys", + "env_filter", + "log", +] + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "atk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241b621213072e993be4f6f3a9e4b45f65b7e6faad43001be957184b7bb1824b" +dependencies = [ + "atk-sys", + "glib", + "libc", +] + +[[package]] +name = "atk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5e48b684b0ca77d2bbadeef17424c2ea3c897d44d566a1617e7e8f30614d086" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" +dependencies = [ + "serde_core", +] + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block2" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" +dependencies = [ + "objc2", +] + +[[package]] +name = "borsh" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1da5ab77c1437701eeff7c88d968729e7766172279eab0676857b3d63af7a6f" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0686c856aa6aac0c4498f936d7d6a02df690f614c03e4d906d1018062b5c5e2c" +dependencies = [ + "once_cell", + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bumpalo" +version = "3.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" + +[[package]] +name = "byte-unit" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6d47a4e2961fb8721bcfc54feae6455f2f64e7054f9bc67e875f0e77f4c58d" +dependencies = [ + "rust_decimal", + "schemars 1.2.0", + "serde", + "utf8-width", +] + +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] + +[[package]] +name = "cairo-rs" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" +dependencies = [ + "bitflags 2.10.0", + "cairo-sys-rs", + "glib", + "libc", + "once_cell", + "thiserror 1.0.69", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685c9fa8e590b8b3d678873528d83411db17242a73fccaed827770ea0fedda51" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "camino" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" +dependencies = [ + "serde_core", +] + +[[package]] +name = "cargo-platform" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e35af189006b9c0f00a064685c727031e3ed2d8020f7ba284d78cc2671bd36ea" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", + "thiserror 2.0.17", +] + +[[package]] +name = "cargo_toml" +version = "0.22.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "374b7c592d9c00c1f4972ea58390ac6b18cbb6ab79011f3bdc90a0b82ca06b77" +dependencies = [ + "serde", + "toml 0.9.11+spec-1.1.0", +] + +[[package]] +name = "cc" +version = "1.2.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd4932aefd12402b36c60956a4fe0035421f544799057659ff86f923657aada3" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cesu8" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" + +[[package]] +name = "cfb" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38f2da7a0a2c4ccf0065be06397cc26a81f4e528be095826eee9d4adbb8c60f" +dependencies = [ + "byteorder", + "fnv", + "uuid", +] + +[[package]] +name = "cfg-expr" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02" +dependencies = [ + "smallvec", + "target-lexicon", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link 0.2.1", +] + +[[package]] +name = "combine" +version = "4.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd" +dependencies = [ + "bytes", + "memchr", +] + +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "time", + "version_check", +] + +[[package]] +name = "core-foundation" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "core-graphics" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" +dependencies = [ + "bitflags 2.10.0", + "core-foundation", + "libc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "cssparser" +version = "0.29.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "matches", + "phf 0.10.1", + "proc-macro2", + "quote", + "smallvec", + "syn 1.0.109", +] + +[[package]] +name = "cssparser-macros" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" +dependencies = [ + "quote", + "syn 2.0.114", +] + +[[package]] +name = "ctor" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +dependencies = [ + "quote", + "syn 2.0.114", +] + +[[package]] +name = "darling" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.114", +] + +[[package]] +name = "darling_macro" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "deranged" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587" +dependencies = [ + "powerfmt", + "serde_core", +] + +[[package]] +name = "derive_more" +version = "0.99.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.114", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.2", +] + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "dlopen2" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e2c5bd4158e66d1e215c49b837e11d62f3267b30c92f1d171c4d3105e3dc4d4" +dependencies = [ + "dlopen2_derive", + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "dlopen2_derive" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbbb781877580993a8707ec48672673ec7b81eeba04cfd2310bd28c08e47c8f" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "dpi" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" +dependencies = [ + "serde", +] + +[[package]] +name = "dtoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c3cf4824e2d5f025c7b531afcb2325364084a16806f6d47fbc1f5fbd9960590" + +[[package]] +name = "dtoa-short" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd1511a7b6a56299bd043a9c167a6d2bfb37bf84a6dfceaba651168adfb43c87" +dependencies = [ + "dtoa", +] + +[[package]] +name = "dunce" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" + +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + +[[package]] +name = "embed-resource" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55a075fc573c64510038d7ee9abc7990635863992f83ebc52c8b433b8411a02e" +dependencies = [ + "cc", + "memchr", + "rustc_version", + "toml 0.9.11+spec-1.1.0", + "vswhom", + "winreg", +] + +[[package]] +name = "embed_plist" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" + +[[package]] +name = "env_filter" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bf3c259d255ca70051b30e2e95b5446cdb8949ac4cd22c0d7fd634d89f568e2" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "erased-serde" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89e8918065695684b2b0702da20382d5ae6065cf3327bc2d6436bd49a71ce9f3" +dependencies = [ + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "fern" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4316185f709b23713e41e3195f90edef7fb00c3ed4adc79769cf09cc762a3b29" +dependencies = [ + "log", +] + +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + +[[package]] +name = "find-msvc-tools" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f449e6c6c08c865631d4890cfacf252b3d396c9bcc83adb6623cdb02a8336c41" + +[[package]] +name = "flate2" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futf" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df420e2e84819663797d1ec6544b13c5be84629e7bb00dc960d6917db2987843" +dependencies = [ + "mac", + "new_debug_unreachable", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "gdk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9f245958c627ac99d8e529166f9823fb3b838d1d41fd2b297af3075093c2691" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk-pixbuf" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50e1f5f1b0bfb830d6ccc8066d18db35c487b1b2b1e8589b5dfe9f07e8defaec" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", + "once_cell", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9839ea644ed9c97a34d129ad56d38a25e6756f99f3a88e15cd39c20629caf7" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c2d13f38594ac1e66619e188c6d5a1adb98d11b2fcf7894fc416ad76aa2f3f7" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkwayland-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "140071d506d223f7572b9f09b5e155afbd77428cd5cc7af8f2694c41d98dfe69" +dependencies = [ + "gdk-sys", + "glib-sys", + "gobject-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gdkx11" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3caa00e14351bebbc8183b3c36690327eb77c49abc2268dd4bd36b856db3fbfe" +dependencies = [ + "gdk", + "gdkx11-sys", + "gio", + "glib", + "libc", + "x11", +] + +[[package]] +name = "gdkx11-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e7445fe01ac26f11601db260dd8608fe172514eb63b3b5e261ea6b0f4428d" +dependencies = [ + "gdk-sys", + "glib-sys", + "libc", + "system-deps", + "x11", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", +] + +[[package]] +name = "gio" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fc8f532f87b79cbc51a79748f16a6828fb784be93145a322fa14d06d354c73" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "once_cell", + "pin-project-lite", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "gio-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37566df850baf5e4cb0dfb78af2e4b9898d817ed9263d1090a2df958c64737d2" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "winapi", +] + +[[package]] +name = "glib" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" +dependencies = [ + "bitflags 2.10.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "once_cell", + "smallvec", + "thiserror 1.0.69", +] + +[[package]] +name = "glib-macros" +version = "0.18.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" +dependencies = [ + "heck 0.4.1", + "proc-macro-crate 2.0.2", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "glib-sys" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "063ce2eb6a8d0ea93d2bf8ba1957e78dbab6be1c2220dd3daca57d5a9d869898" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "gobject-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0850127b514d1c4a4654ead6dedadb18198999985908e6ffe4436f53c785ce44" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gtk" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56fb197bfc42bd5d2751f4f017d44ff59fbb58140c6b49f9b3b2bdab08506a" +dependencies = [ + "atk", + "cairo-rs", + "field-offset", + "futures-channel", + "gdk", + "gdk-pixbuf", + "gio", + "glib", + "gtk-sys", + "gtk3-macros", + "libc", + "pango", + "pkg-config", +] + +[[package]] +name = "gtk-sys" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f29a1c21c59553eb7dd40e918be54dccd60c52b049b75119d5d96ce6b624414" +dependencies = [ + "atk-sys", + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk3-macros" +version = "0.18.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ff3c5b21f14f0736fed6dcfc0bfb4225ebf5725f3c0209edeec181e4d73e9d" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "html5ever" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" +dependencies = [ + "log", + "mac", + "markup5ever", + "match_token", +] + +[[package]] +name = "http" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.62.2", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ico" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc50b891e4acf8fe0e71ef88ec43ad82ee07b3810ad09de10f1d01f072ed4b98" +dependencies = [ + "byteorder", + "png", +] + +[[package]] +name = "icu_collections" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +dependencies = [ + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" + +[[package]] +name = "icu_properties" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +dependencies = [ + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" + +[[package]] +name = "icu_provider" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +dependencies = [ + "displaydoc", + "icu_locale_core", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +dependencies = [ + "equivalent", + "hashbrown 0.16.1", + "serde", + "serde_core", +] + +[[package]] +name = "infer" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" +dependencies = [ + "cfb", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "itoa" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" + +[[package]] +name = "javascriptcore-rs" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca5671e9ffce8ffba57afc24070e906da7fc4b1ba66f2cabebf61bf2ea257fcc" +dependencies = [ + "bitflags 1.3.2", + "glib", + "javascriptcore-rs-sys", +] + +[[package]] +name = "javascriptcore-rs-sys" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1be78d14ffa4b75b66df31840478fef72b51f8c2465d4ca7c194da9f7a5124" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "jni" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +dependencies = [ + "cesu8", + "cfg-if", + "combine", + "jni-sys", + "log", + "thiserror 1.0.69", + "walkdir", + "windows-sys 0.45.0", +] + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "js-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "863726d7afb6bc2590eeff7135d923545e5e964f004c2ccf8716c25e70a86f08" +dependencies = [ + "jsonptr", + "serde", + "serde_json", + "thiserror 1.0.69", +] + +[[package]] +name = "jsonptr" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dea2b27dd239b2556ed7a25ba842fe47fd602e7fc7433c2a8d6106d4d9edd70" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "keyboard-types" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" +dependencies = [ + "bitflags 2.10.0", + "serde", + "unicode-segmentation", +] + +[[package]] +name = "kuchikiki" +version = "0.8.8-speedreader" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" +dependencies = [ + "cssparser", + "html5ever", + "indexmap 2.13.0", + "selectors", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libappindicator" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03589b9607c868cc7ae54c0b2a22c8dc03dd41692d48f2d7df73615c6a95dc0a" +dependencies = [ + "glib", + "gtk", + "gtk-sys", + "libappindicator-sys", + "log", +] + +[[package]] +name = "libappindicator-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" +dependencies = [ + "gtk-sys", + "libloading", + "once_cell", +] + +[[package]] +name = "libc" +version = "0.2.180" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" + +[[package]] +name = "libloading" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f" +dependencies = [ + "cfg-if", + "winapi", +] + +[[package]] +name = "libredox" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" +dependencies = [ + "bitflags 2.10.0", + "libc", +] + +[[package]] +name = "litemap" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +dependencies = [ + "value-bag", +] + +[[package]] +name = "mac" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" + +[[package]] +name = "markup5ever" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a7213d12e1864c0f002f52c2923d4556935a43dec5e71355c2760e0f6e7a18" +dependencies = [ + "log", + "phf 0.11.3", + "phf_codegen 0.11.3", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "match_token" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "matches" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" + +[[package]] +name = "memchr" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" + +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +dependencies = [ + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.61.2", +] + +[[package]] +name = "muda" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +dependencies = [ + "crossbeam-channel", + "dpi", + "gtk", + "keyboard-types", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "once_cell", + "png", + "serde", + "thiserror 2.0.17", + "windows-sys 0.60.2", +] + +[[package]] +name = "ndk" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" +dependencies = [ + "bitflags 2.10.0", + "jni-sys", + "log", + "ndk-sys", + "num_enum", + "raw-window-handle", + "thiserror 1.0.69", +] + +[[package]] +name = "ndk-context" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27b02d87554356db9e9a873add8782d4ea6e3e58ea071a9adb9a2e8ddb884a8b" + +[[package]] +name = "ndk-sys" +version = "0.6.0+11769913" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" +dependencies = [ + "jni-sys", +] + +[[package]] +name = "new_debug_unreachable" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" + +[[package]] +name = "nodrop" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_enum" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" +dependencies = [ + "num_enum_derive", + "rustversion", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" +dependencies = [ + "proc-macro-crate 3.4.0", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "num_threads" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7398b9c8b70908f6371f47ed36737907c87c52af34c268fed0bf0ceb92ead9" +dependencies = [ + "libc", +] + +[[package]] +name = "objc2" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c2599ce0ec54857b29ce62166b0ed9b4f6f1a70ccc9a71165b6154caca8c05" +dependencies = [ + "objc2-encode", + "objc2-exception-helper", +] + +[[package]] +name = "objc2-app-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d49e936b501e5c5bf01fda3a9452ff86dc3ea98ad5f283e1455153142d97518c" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", + "objc2-cloud-kit", + "objc2-core-data", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-text", + "objc2-core-video", + "objc2-foundation", + "objc2-quartz-core", +] + +[[package]] +name = "objc2-cloud-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73ad74d880bb43877038da939b7427bba67e9dd42004a18b809ba7d87cee241c" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b402a653efbb5e82ce4df10683b6b28027616a2715e90009947d50b8dd298fa" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a180dd8642fa45cdb7dd721cd4c11b1cadd4929ce112ebd8b9f5803cc79d536" +dependencies = [ + "bitflags 2.10.0", + "dispatch2", + "objc2", +] + +[[package]] +name = "objc2-core-graphics" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e022c9d066895efa1345f8e33e584b9f958da2fd4cd116792e15e07e4720a807" +dependencies = [ + "bitflags 2.10.0", + "dispatch2", + "objc2", + "objc2-core-foundation", + "objc2-io-surface", +] + +[[package]] +name = "objc2-core-image" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d563b38d2b97209f8e861173de434bd0214cf020e3423a52624cd1d989f006" +dependencies = [ + "objc2", + "objc2-foundation", +] + +[[package]] +name = "objc2-core-text" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde0dfb48d25d2b4862161a4d5fcc0e3c24367869ad306b0c9ec0073bfed92d" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", +] + +[[package]] +name = "objc2-core-video" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d425caf1df73233f29fd8a5c3e5edbc30d2d4307870f802d18f00d83dc5141a6" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-io-surface", +] + +[[package]] +name = "objc2-encode" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" + +[[package]] +name = "objc2-exception-helper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7a1c5fbb72d7735b076bb47b578523aedc40f3c439bea6dfd595c089d79d98a" +dependencies = [ + "cc", +] + +[[package]] +name = "objc2-foundation" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3e0adef53c21f888deb4fa59fc59f7eb17404926ee8a6f59f5df0fd7f9f3272" +dependencies = [ + "bitflags 2.10.0", + "block2", + "libc", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-io-surface" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180788110936d59bab6bd83b6060ffdfffb3b922ba1396b312ae795e1de9d81d" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-javascript-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a1e6550c4caed348956ce3370c9ffeca70bb1dbed4fa96112e7c6170e074586" +dependencies = [ + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-quartz-core" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c1358452b371bf9f104e21ec536d37a650eb10f7ee379fff67d2e08d537f1f" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-security" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "709fe137109bd1e8b5a99390f77a7d8b2961dafc1a1c5db8f2e60329ad6d895a" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", +] + +[[package]] +name = "objc2-ui-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22" +dependencies = [ + "bitflags 2.10.0", + "objc2", + "objc2-core-foundation", + "objc2-foundation", +] + +[[package]] +name = "objc2-web-kit" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e5aaab980c433cf470df9d7af96a7b46a9d892d521a2cbbb2f8a4c16751e7f" +dependencies = [ + "bitflags 2.10.0", + "block2", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-javascript-core", + "objc2-security", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pango" +version = "0.18.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca27ec1eb0457ab26f3036ea52229edbdb74dee1edd29063f5b9b010e7ebee4" +dependencies = [ + "gio", + "glib", + "libc", + "once_cell", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436737e391a843e5933d6d9aa102cb126d501e815b83601365a948a518555dc5" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "phf" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12" +dependencies = [ + "phf_shared 0.8.0", +] + +[[package]] +name = "phf" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" +dependencies = [ + "phf_macros 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", +] + +[[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_macros 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_codegen" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbffee61585b0411840d3ece935cce9cb6321f01c45477d30066498cd5e1a815" +dependencies = [ + "phf_generator 0.8.0", + "phf_shared 0.8.0", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", +] + +[[package]] +name = "phf_generator" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526" +dependencies = [ + "phf_shared 0.8.0", + "rand 0.7.3", +] + +[[package]] +name = "phf_generator" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" +dependencies = [ + "phf_shared 0.10.0", + "rand 0.8.5", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared 0.11.3", + "rand 0.8.5", +] + +[[package]] +name = "phf_macros" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" +dependencies = [ + "phf_generator 0.10.0", + "phf_shared 0.10.0", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "phf_macros" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f84ac04429c13a7ff43785d75ad27569f2951ce0ffd30a3321230db2fc727216" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "phf_shared" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher 1.0.1", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "plist" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740ebea15c5d1428f910cd1a5f52cebf8d25006245ed8ade92702f4943d91e07" +dependencies = [ + "base64 0.22.1", + "indexmap 2.13.0", + "quick-xml 0.38.4", + "serde", + "time", +] + +[[package]] +name = "png" +version = "0.17.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526" +dependencies = [ + "bitflags 1.3.2", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "potential_utf" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +dependencies = [ + "zerovec", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit 0.19.15", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +dependencies = [ + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "proc-macro-crate" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" +dependencies = [ + "toml_edit 0.23.10+spec-1.0.0", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.20+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" + +[[package]] +name = "proc-macro2" +version = "1.0.105" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "535d180e0ecab6268a3e718bb9fd44db66bbbc256257165fc699dadf70d16fe7" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "quick-xml" +version = "0.37.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" +dependencies = [ + "memchr", +] + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + +[[package]] +name = "quote" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74d9a594b72ae6656596548f56f667211f8a97b3d4c3d467150794690dc40a" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", + "rand_pcg", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.17", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_pcg" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "raw-window-handle" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags 2.10.0", +] + +[[package]] +name = "redox_users" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" +dependencies = [ + "getrandom 0.2.17", + "libredox", + "thiserror 2.0.17", +] + +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "reqwest" +version = "0.12.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" +dependencies = [ + "base64 0.22.1", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "js-sys", + "log", + "percent-encoding", + "pin-project-lite", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", +] + +[[package]] +name = "rfd" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15ad77d9e70a92437d8f74c35d99b4e4691128df018833e99f90bcd36152672" +dependencies = [ + "block2", + "dispatch2", + "glib-sys", + "gobject-sys", + "gtk-sys", + "js-sys", + "log", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-sys 0.60.2", +] + +[[package]] +name = "rkyv" +version = "0.7.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2297bf9c81a3f0dc96bc9521370b88f054168c29826a75e89c55ff196e7ed6a1" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d7b42d4b8d06048d3ac8db0eb31bcb942cbeb709f0b5f2b2ebde398d3038f5" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61f703d19852dbf87cbc513643fa81428361eb6940f1ac14fd58155d295a3eb0" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand 0.8.5", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a50f4cf475b65d88e057964e0e9bb1f0aa9bbb2036dc65c64596b42932536984" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", + "url", + "uuid", +] + +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.114", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "selectors" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" +dependencies = [ + "bitflags 1.3.2", + "cssparser", + "derive_more", + "fxhash", + "log", + "phf 0.8.0", + "phf_codegen 0.8.0", + "precomputed-hash", + "servo_arc", + "smallvec", +] + +[[package]] +name = "semver" +version = "1.0.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +dependencies = [ + "serde", + "serde_core", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-untagged" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058" +dependencies = [ + "erased-serde", + "serde", + "serde_core", + "typeid", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_json" +version = "1.0.149" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_repr" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serde_spanned" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_with" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7" +dependencies = [ + "base64 0.22.1", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.13.0", + "schemars 0.9.0", + "schemars 1.2.0", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "serialize-to-javascript" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04f3666a07a197cdb77cdf306c32be9b7f598d7060d50cfd4d5aa04bfd92f6c5" +dependencies = [ + "serde", + "serde_json", + "serialize-to-javascript-impl", +] + +[[package]] +name = "serialize-to-javascript-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "servo_arc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" +dependencies = [ + "nodrop", + "stable_deref_trait", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "simd-adler32" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "sms-backup-viewer" +version = "0.26.0" +dependencies = [ + "log", + "quick-xml 0.37.5", + "serde", + "serde_json", + "tauri", + "tauri-build", + "tauri-plugin-dialog", + "tauri-plugin-fs", + "tauri-plugin-log", +] + +[[package]] +name = "socket2" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881" +dependencies = [ + "libc", + "windows-sys 0.60.2", +] + +[[package]] +name = "softbuffer" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" +dependencies = [ + "bytemuck", + "js-sys", + "ndk", + "objc2", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "objc2-quartz-core", + "raw-window-handle", + "redox_syscall", + "tracing", + "wasm-bindgen", + "web-sys", + "windows-sys 0.61.2", +] + +[[package]] +name = "soup3" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471f924a40f31251afc77450e781cb26d55c0b650842efafc9c6cbd2f7cc4f9f" +dependencies = [ + "futures-channel", + "gio", + "glib", + "libc", + "soup3-sys", +] + +[[package]] +name = "soup3-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebe8950a680a12f24f15ebe1bf70db7af98ad242d9db43596ad3108aab86c27" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" + +[[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.11.3", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator 0.11.3", + "phf_shared 0.11.3", + "proc-macro2", + "quote", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "swift-rs" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4057c98e2e852d51fdcfca832aac7b571f6b351ad159f9eda5db1655f8d0c4d7" +dependencies = [ + "base64 0.21.7", + "serde", + "serde_json", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.114" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "system-deps" +version = "6.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349" +dependencies = [ + "cfg-expr", + "heck 0.5.0", + "pkg-config", + "toml 0.8.2", + "version-compare", +] + +[[package]] +name = "tao" +version = "0.34.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" +dependencies = [ + "bitflags 2.10.0", + "block2", + "core-foundation", + "core-graphics", + "crossbeam-channel", + "dispatch", + "dlopen2", + "dpi", + "gdkwayland-sys", + "gdkx11-sys", + "gtk", + "jni", + "lazy_static", + "libc", + "log", + "ndk", + "ndk-context", + "ndk-sys", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "parking_lot", + "raw-window-handle", + "scopeguard", + "tao-macros", + "unicode-segmentation", + "url", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "tao-macros" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "tauri" +version = "2.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a3868da5508446a7cd08956d523ac3edf0a8bc20bf7e4038f9a95c2800d2033" +dependencies = [ + "anyhow", + "bytes", + "cookie", + "dirs", + "dunce", + "embed_plist", + "getrandom 0.3.4", + "glob", + "gtk", + "heck 0.5.0", + "http", + "jni", + "libc", + "log", + "mime", + "muda", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "percent-encoding", + "plist", + "raw-window-handle", + "reqwest", + "serde", + "serde_json", + "serde_repr", + "serialize-to-javascript", + "swift-rs", + "tauri-build", + "tauri-macros", + "tauri-runtime", + "tauri-runtime-wry", + "tauri-utils", + "thiserror 2.0.17", + "tokio", + "tray-icon", + "url", + "webkit2gtk", + "webview2-com", + "window-vibrancy", + "windows", +] + +[[package]] +name = "tauri-build" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17fcb8819fd16463512a12f531d44826ce566f486d7ccd211c9c8cebdaec4e08" +dependencies = [ + "anyhow", + "cargo_toml", + "dirs", + "glob", + "heck 0.5.0", + "json-patch", + "schemars 0.8.22", + "semver", + "serde", + "serde_json", + "tauri-utils", + "tauri-winres", + "toml 0.9.11+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-codegen" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa9844cefcf99554a16e0a278156ae73b0d8680bbc0e2ad1e4287aadd8489cf" +dependencies = [ + "base64 0.22.1", + "brotli", + "ico", + "json-patch", + "plist", + "png", + "proc-macro2", + "quote", + "semver", + "serde", + "serde_json", + "sha2", + "syn 2.0.114", + "tauri-utils", + "thiserror 2.0.17", + "time", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-macros" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3764a12f886d8245e66b7ee9b43ccc47883399be2019a61d80cf0f4117446fde" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.114", + "tauri-codegen", + "tauri-utils", +] + +[[package]] +name = "tauri-plugin" +version = "2.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1d0a4860b7ff570c891e1d2a586bf1ede205ff858fbc305e0b5ae5d14c1377" +dependencies = [ + "anyhow", + "glob", + "plist", + "schemars 0.8.22", + "serde", + "serde_json", + "tauri-utils", + "toml 0.9.11+spec-1.1.0", + "walkdir", +] + +[[package]] +name = "tauri-plugin-dialog" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9204b425d9be8d12aa60c2a83a289cf7d1caae40f57f336ed1155b3a5c0e359b" +dependencies = [ + "log", + "raw-window-handle", + "rfd", + "serde", + "serde_json", + "tauri", + "tauri-plugin", + "tauri-plugin-fs", + "thiserror 2.0.17", + "url", +] + +[[package]] +name = "tauri-plugin-fs" +version = "2.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed390cc669f937afeb8b28032ce837bac8ea023d975a2e207375ec05afaf1804" +dependencies = [ + "anyhow", + "dunce", + "glob", + "percent-encoding", + "schemars 0.8.22", + "serde", + "serde_json", + "serde_repr", + "tauri", + "tauri-plugin", + "tauri-utils", + "thiserror 2.0.17", + "toml 0.9.11+spec-1.1.0", + "url", +] + +[[package]] +name = "tauri-plugin-log" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7545bd67f070a4500432c826e2e0682146a1d6712aee22a2786490156b574d93" +dependencies = [ + "android_logger", + "byte-unit", + "fern", + "log", + "objc2", + "objc2-foundation", + "serde", + "serde_json", + "serde_repr", + "swift-rs", + "tauri", + "tauri-plugin", + "thiserror 2.0.17", + "time", +] + +[[package]] +name = "tauri-runtime" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f766fe9f3d1efc4b59b17e7a891ad5ed195fa8d23582abb02e6c9a01137892" +dependencies = [ + "cookie", + "dpi", + "gtk", + "http", + "jni", + "objc2", + "objc2-ui-kit", + "objc2-web-kit", + "raw-window-handle", + "serde", + "serde_json", + "tauri-utils", + "thiserror 2.0.17", + "url", + "webkit2gtk", + "webview2-com", + "windows", +] + +[[package]] +name = "tauri-runtime-wry" +version = "2.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "187a3f26f681bdf028f796ccf57cf478c1ee422c50128e5a0a6ebeb3f5910065" +dependencies = [ + "gtk", + "http", + "jni", + "log", + "objc2", + "objc2-app-kit", + "objc2-foundation", + "once_cell", + "percent-encoding", + "raw-window-handle", + "softbuffer", + "tao", + "tauri-runtime", + "tauri-utils", + "url", + "webkit2gtk", + "webview2-com", + "windows", + "wry", +] + +[[package]] +name = "tauri-utils" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a423c51176eb3616ee9b516a9fa67fed5f0e78baaba680e44eb5dd2cc37490" +dependencies = [ + "anyhow", + "brotli", + "cargo_metadata", + "ctor", + "dunce", + "glob", + "html5ever", + "http", + "infer", + "json-patch", + "kuchikiki", + "log", + "memchr", + "phf 0.11.3", + "proc-macro2", + "quote", + "regex", + "schemars 0.8.22", + "semver", + "serde", + "serde-untagged", + "serde_json", + "serde_with", + "swift-rs", + "thiserror 2.0.17", + "toml 0.9.11+spec-1.1.0", + "url", + "urlpattern", + "uuid", + "walkdir", +] + +[[package]] +name = "tauri-winres" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1087b111fe2b005e42dbdc1990fc18593234238d47453b0c99b7de1c9ab2c1e0" +dependencies = [ + "dunce", + "embed-resource", + "toml 0.9.11+spec-1.1.0", +] + +[[package]] +name = "tendril" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d24a120c5fc464a3458240ee02c299ebcb9d67b5249c8848b09d639dca8d7bb0" +dependencies = [ + "futf", + "mac", + "utf-8", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "time" +version = "0.3.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" +dependencies = [ + "deranged", + "itoa", + "libc", + "num-conv", + "num_threads", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" + +[[package]] +name = "time-macros" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinyvec" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa5fdc3bce6191a1dbc8c02d5c8bffcf557bafa17c124c5264a458f1b0613fa" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.49.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86" +dependencies = [ + "bytes", + "libc", + "mio", + "pin-project-lite", + "socket2", + "windows-sys 0.61.2", +] + +[[package]] +name = "tokio-util" +version = "0.7.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae9cec805b01e8fc3fd2fe289f89149a9b66dd16786abd8b19cfa7b48cb0098" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +dependencies = [ + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "toml_edit 0.20.2", +] + +[[package]] +name = "toml" +version = "0.9.11+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" +dependencies = [ + "indexmap 2.13.0", + "serde_core", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.14", +] + +[[package]] +name = "toml_datetime" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +dependencies = [ + "indexmap 2.13.0", + "serde", + "serde_spanned 0.6.9", + "toml_datetime 0.6.3", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.23.10+spec-1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" +dependencies = [ + "indexmap 2.13.0", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "winnow 0.7.14", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow 0.7.14", +] + +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +dependencies = [ + "bitflags 2.10.0", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "pin-project-lite", + "tracing-core", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", +] + +[[package]] +name = "tray-icon" +version = "0.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e85aa143ceb072062fc4d6356c1b520a51d636e7bc8e77ec94be3608e5e80c" +dependencies = [ + "crossbeam-channel", + "dirs", + "libappindicator", + "muda", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-core-graphics", + "objc2-foundation", + "once_cell", + "png", + "serde", + "thiserror 2.0.17", + "windows-sys 0.60.2", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + +[[package]] +name = "typenum" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" + +[[package]] +name = "unic-char-property" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" +dependencies = [ + "unic-char-range", +] + +[[package]] +name = "unic-char-range" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" + +[[package]] +name = "unic-common" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" + +[[package]] +name = "unic-ucd-ident" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987" +dependencies = [ + "unic-char-property", + "unic-char-range", + "unic-ucd-version", +] + +[[package]] +name = "unic-ucd-version" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" +dependencies = [ + "unic-common", +] + +[[package]] +name = "unicode-ident" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "url" +version = "2.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff67a8a4397373c3ef660812acab3268222035010ab8680ec4215f38ba3d0eed" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", + "serde_derive", +] + +[[package]] +name = "urlpattern" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70acd30e3aa1450bc2eece896ce2ad0d178e9c079493819301573dae3c37ba6d" +dependencies = [ + "regex", + "serde", + "unic-ucd-ident", + "url", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1292c0d970b54115d14f2492fe0170adf21d68a1de108eebc51c1df4f346a091" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "getrandom 0.3.4", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "value-bag" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ba6f5989077681266825251a52748b8c1d8a4ad098cc37e440103d0ea717fc0" + +[[package]] +name = "version-compare" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "vswhom" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b" +dependencies = [ + "libc", + "vswhom-sys", +] + +[[package]] +name = "vswhom-sys" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb067e4cbd1ff067d1df46c9194b5de0e98efd2810bbc95c5d5e5f25a3231150" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.2+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.58" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" +dependencies = [ + "cfg-if", + "futures-util", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn 2.0.114", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.108" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.85" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webkit2gtk" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76b1bc1e54c581da1e9f179d0b38512ba358fb1af2d634a1affe42e37172361a" +dependencies = [ + "bitflags 1.3.2", + "cairo-rs", + "gdk", + "gdk-sys", + "gio", + "gio-sys", + "glib", + "glib-sys", + "gobject-sys", + "gtk", + "gtk-sys", + "javascriptcore-rs", + "libc", + "once_cell", + "soup3", + "webkit2gtk-sys", +] + +[[package]] +name = "webkit2gtk-sys" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62daa38afc514d1f8f12b8693d30d5993ff77ced33ce30cd04deebc267a6d57c" +dependencies = [ + "bitflags 1.3.2", + "cairo-sys-rs", + "gdk-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk-sys", + "javascriptcore-rs-sys", + "libc", + "pkg-config", + "soup3-sys", + "system-deps", +] + +[[package]] +name = "webview2-com" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7130243a7a5b33c54a444e54842e6a9e133de08b5ad7b5861cd8ed9a6a5bc96a" +dependencies = [ + "webview2-com-macros", + "webview2-com-sys", + "windows", + "windows-core 0.61.2", + "windows-implement", + "windows-interface", +] + +[[package]] +name = "webview2-com-macros" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "webview2-com-sys" +version = "0.38.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" +dependencies = [ + "thiserror 2.0.17", + "windows", + "windows-core 0.61.2", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window-vibrancy" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" +dependencies = [ + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "raw-window-handle", + "windows-sys 0.59.0", + "windows-version", +] + +[[package]] +name = "windows" +version = "0.61.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link 0.1.3", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", + "windows-threading", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-numerics" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" +dependencies = [ + "windows-core 0.61.2", + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link 0.2.1", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4060a1da109b9d0326b7262c8e12c84df67cc0dbc9e33cf49e01ccc2eb63631" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.55.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb5a765337c50e9ec252c2069be9bf91c7df47afb103b642ba3a53bf8101be97" +dependencies = [ + "cfg-if", + "windows-sys 0.59.0", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" + +[[package]] +name = "writeable" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" + +[[package]] +name = "wry" +version = "0.53.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728b7d4c8ec8d81cab295e0b5b8a4c263c0d41a785fb8f8c4df284e5411140a2" +dependencies = [ + "base64 0.22.1", + "block2", + "cookie", + "crossbeam-channel", + "dirs", + "dpi", + "dunce", + "gdkx11", + "gtk", + "html5ever", + "http", + "javascriptcore-rs", + "jni", + "kuchikiki", + "libc", + "ndk", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", + "objc2-ui-kit", + "objc2-web-kit", + "once_cell", + "percent-encoding", + "raw-window-handle", + "sha2", + "soup3", + "tao-macros", + "thiserror 2.0.17", + "url", + "webkit2gtk", + "webkit2gtk-sys", + "webview2-com", + "windows", + "windows-core 0.61.2", + "windows-version", + "x11-dl", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x11" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "502da5464ccd04011667b11c435cb992822c2c0dbde1770c988480d312a0db2e" +dependencies = [ + "libc", + "pkg-config", +] + +[[package]] +name = "x11-dl" +version = "2.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f" +dependencies = [ + "libc", + "once_cell", + "pkg-config", +] + +[[package]] +name = "yoke" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +dependencies = [ + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", + "synstructure", +] + +[[package]] +name = "zerotrie" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.114", +] + +[[package]] +name = "zmij" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd8f3f50b848df28f887acb68e41201b5aea6bc8a8dacc00fb40635ff9a72fea" diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml new file mode 100644 index 0000000..3583586 --- /dev/null +++ b/src-tauri/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "sms-backup-viewer" +version = "0.26.0" +description = "SMS Backup Viewer" +authors = ["you"] +license = "" +repository = "" +edition = "2021" +rust-version = "1.77.2" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +name = "app_lib" +crate-type = ["staticlib", "cdylib", "rlib"] + +[build-dependencies] +tauri-build = { version = "2.5.3", features = [] } + +[dependencies] +serde_json = "1.0" +serde = { version = "1.0", features = ["derive"] } +log = "0.4" +tauri = { version = "2.9.5", features = [] } +tauri-plugin-log = "2" +tauri-plugin-dialog = "2" +tauri-plugin-fs = "2" +quick-xml = "0.37" diff --git a/src-tauri/build.rs b/src-tauri/build.rs new file mode 100644 index 0000000..795b9b7 --- /dev/null +++ b/src-tauri/build.rs @@ -0,0 +1,3 @@ +fn main() { + tauri_build::build() +} diff --git a/src-tauri/capabilities/default.json b/src-tauri/capabilities/default.json new file mode 100644 index 0000000..96d0efe --- /dev/null +++ b/src-tauri/capabilities/default.json @@ -0,0 +1,12 @@ +{ + "$schema": "../gen/schemas/desktop-schema.json", + "identifier": "default", + "description": "enables the default permissions", + "windows": [ + "main" + ], + "permissions": [ + "core:default", + "dialog:default" + ] +} diff --git a/src-tauri/icons/128x128.png b/src-tauri/icons/128x128.png new file mode 100644 index 0000000..77e7d23 Binary files /dev/null and b/src-tauri/icons/128x128.png differ diff --git a/src-tauri/icons/128x128@2x.png b/src-tauri/icons/128x128@2x.png new file mode 100644 index 0000000..0f7976f Binary files /dev/null and b/src-tauri/icons/128x128@2x.png differ diff --git a/src-tauri/icons/32x32.png b/src-tauri/icons/32x32.png new file mode 100644 index 0000000..98fda06 Binary files /dev/null and b/src-tauri/icons/32x32.png differ diff --git a/src-tauri/icons/Square107x107Logo.png b/src-tauri/icons/Square107x107Logo.png new file mode 100644 index 0000000..f35d84f Binary files /dev/null and b/src-tauri/icons/Square107x107Logo.png differ diff --git a/src-tauri/icons/Square142x142Logo.png b/src-tauri/icons/Square142x142Logo.png new file mode 100644 index 0000000..1823bb2 Binary files /dev/null and b/src-tauri/icons/Square142x142Logo.png differ diff --git a/src-tauri/icons/Square150x150Logo.png b/src-tauri/icons/Square150x150Logo.png new file mode 100644 index 0000000..dc2b22c Binary files /dev/null and b/src-tauri/icons/Square150x150Logo.png differ diff --git a/src-tauri/icons/Square284x284Logo.png b/src-tauri/icons/Square284x284Logo.png new file mode 100644 index 0000000..0ed3984 Binary files /dev/null and b/src-tauri/icons/Square284x284Logo.png differ diff --git a/src-tauri/icons/Square30x30Logo.png b/src-tauri/icons/Square30x30Logo.png new file mode 100644 index 0000000..60bf0ea Binary files /dev/null and b/src-tauri/icons/Square30x30Logo.png differ diff --git a/src-tauri/icons/Square310x310Logo.png b/src-tauri/icons/Square310x310Logo.png new file mode 100644 index 0000000..c8ca0ad Binary files /dev/null and b/src-tauri/icons/Square310x310Logo.png differ diff --git a/src-tauri/icons/Square44x44Logo.png b/src-tauri/icons/Square44x44Logo.png new file mode 100644 index 0000000..8756459 Binary files /dev/null and b/src-tauri/icons/Square44x44Logo.png differ diff --git a/src-tauri/icons/Square71x71Logo.png b/src-tauri/icons/Square71x71Logo.png new file mode 100644 index 0000000..2c8023c Binary files /dev/null and b/src-tauri/icons/Square71x71Logo.png differ diff --git a/src-tauri/icons/Square89x89Logo.png b/src-tauri/icons/Square89x89Logo.png new file mode 100644 index 0000000..2c5e603 Binary files /dev/null and b/src-tauri/icons/Square89x89Logo.png differ diff --git a/src-tauri/icons/StoreLogo.png b/src-tauri/icons/StoreLogo.png new file mode 100644 index 0000000..17d142c Binary files /dev/null and b/src-tauri/icons/StoreLogo.png differ diff --git a/src-tauri/icons/icon.icns b/src-tauri/icons/icon.icns new file mode 100644 index 0000000..a2993ad Binary files /dev/null and b/src-tauri/icons/icon.icns differ diff --git a/src-tauri/icons/icon.ico b/src-tauri/icons/icon.ico new file mode 100644 index 0000000..06c23c8 Binary files /dev/null and b/src-tauri/icons/icon.ico differ diff --git a/src-tauri/icons/icon.png b/src-tauri/icons/icon.png new file mode 100644 index 0000000..d1756ce Binary files /dev/null and b/src-tauri/icons/icon.png differ diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs new file mode 100644 index 0000000..487fa2b --- /dev/null +++ b/src-tauri/src/lib.rs @@ -0,0 +1,58 @@ +use tauri::Emitter; + +#[cfg_attr(mobile, tauri::mobile_entry_point)] +pub fn run() { + tauri::Builder::default() + .setup(|app| { + let handle = app.handle(); + handle + .plugin(tauri_plugin_dialog::init()) + .map_err(|e| e.to_string())?; + handle + .plugin(tauri_plugin_fs::init()) + .map_err(|e| e.to_string())?; + if cfg!(debug_assertions) { + app.handle().plugin( + tauri_plugin_log::Builder::default() + .level(log::LevelFilter::Info) + .build(), + )?; + } + Ok(()) + }) + .invoke_handler(tauri::generate_handler![start_parse_sms_backup]) + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} + +mod sms_backup_parser; + +#[tauri::command] +fn start_parse_sms_backup(window: tauri::Window, path: String) -> Result<(), String> { + std::thread::spawn(move || { + let path = std::path::PathBuf::from(path); + + let emit_batch = |batch: sms_backup_parser::ParseBatch| -> Result<(), String> { + window + .emit("sms_parse_batch", batch) + .map_err(|e| format!("Failed to emit batch event: {e}")) + }; + + let emit_progress = |progress: sms_backup_parser::ParseProgress| -> Result<(), String> { + window + .emit("sms_parse_progress", progress) + .map_err(|e| format!("Failed to emit progress event: {e}")) + }; + + match sms_backup_parser::parse_sms_backup_streaming(&path, emit_batch, emit_progress) { + Ok(done) => { + let _ = window.emit("sms_parse_done", done); + } + Err(err) => { + let _ = window.emit("sms_parse_error", err); + } + } + }); + + Ok(()) +} diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs new file mode 100644 index 0000000..ad5fe83 --- /dev/null +++ b/src-tauri/src/main.rs @@ -0,0 +1,6 @@ +// Prevents additional console window on Windows in release, DO NOT REMOVE!! +#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] + +fn main() { + app_lib::run(); +} diff --git a/src-tauri/src/sms_backup_parser.rs b/src-tauri/src/sms_backup_parser.rs new file mode 100644 index 0000000..5073e83 --- /dev/null +++ b/src-tauri/src/sms_backup_parser.rs @@ -0,0 +1,334 @@ +use serde::Serialize; +use std::{ + collections::BTreeMap, + fs::File, + io::{BufRead, BufReader}, + path::Path, +}; + +use quick_xml::{ + events::{BytesStart, Event}, + Reader, +}; + +#[derive(Debug, Clone, Serialize)] +#[allow(non_snake_case)] +pub struct ParsedMessage { + pub contactAddress: String, + pub contactName: Option, + pub r#type: i32, + pub timestamp: String, + pub dateMs: i64, + pub body: String, +} + +#[derive(Debug, Clone, Serialize)] +#[allow(non_snake_case)] +pub struct ParseBatch { + pub messages: Vec, + pub bytesRead: u64, + pub totalBytes: u64, + pub parsedCount: u64, +} + +#[derive(Debug, Clone, Serialize)] +#[allow(non_snake_case)] +pub struct ParseProgress { + pub bytesRead: u64, + pub totalBytes: u64, + pub parsedCount: u64, +} + +#[derive(Debug, Clone, Serialize)] +#[allow(non_snake_case)] +pub struct ParseDone { + pub bytesRead: u64, + pub totalBytes: u64, + pub parsedCount: u64, +} + +fn attr_value(reader: &Reader, start: &BytesStart, key: &[u8]) -> Option { + for attr in start.attributes().with_checks(false).flatten() { + if attr.key.as_ref() == key { + if let Ok(v) = attr.decode_and_unescape_value(reader.decoder()) { + return Some(v.into_owned()); + } + } + } + None +} + +fn parse_i32(s: Option, default: i32) -> i32 { + s.and_then(|v| v.parse::().ok()).unwrap_or(default) +} + +fn parse_i64(s: Option, default: i64) -> i64 { + s.and_then(|v| v.parse::().ok()).unwrap_or(default) +} + +fn mms_body(text_parts: &[String], media_counts: &BTreeMap) -> String { + let mut out = String::new(); + + for t in text_parts { + if !t.is_empty() { + out.push_str("
"); + out.push_str(t); + out.push_str("
"); + } + } + + let total_media: u32 = media_counts.values().copied().sum(); + if total_media > 0 { + out.push_str("
"); + out.push_str(&format!( + "[{} attachment{} omitted]", + total_media, + if total_media == 1 { "" } else { "s" } + )); + + if !media_counts.is_empty() { + out.push_str(" "); + let mut first = true; + for (ct, count) in media_counts { + if !first { + out.push_str(", "); + } + first = false; + out.push_str(&format!("{}×{}", count, ct)); + } + } + + out.push_str("
"); + } + + out +} + +struct MmsAcc { + contact_address: String, + r#type: i32, + text_parts: Vec, + media_counts: BTreeMap, +} + +fn parse_mms_inner( + reader: &mut Reader, + parsed_count: u64, +) -> Result<(MmsAcc, u64, u64), String> { + let mut buf = Vec::new(); + let mut acc = MmsAcc { + contact_address: String::new(), + r#type: 3, + text_parts: Vec::new(), + media_counts: BTreeMap::new(), + }; + + loop { + match reader.read_event_into(&mut buf) { + Ok(Event::Start(e)) => { + match e.local_name().as_ref() { + b"addr" => { + if let Some(addr_type) = attr_value(reader, &e, b"type") { + if let Some(address) = attr_value(reader, &e, b"address") { + if addr_type == "137" || acc.contact_address == "insert-address-token" { + acc.contact_address = address; + } + if acc.contact_address == "insert-address-token" { + acc.r#type = 4; + } + } + } + } + _ => {} + } + } + Ok(Event::Empty(e)) => { + match e.local_name().as_ref() { + b"addr" => { + if let Some(addr_type) = attr_value(reader, &e, b"type") { + if let Some(address) = attr_value(reader, &e, b"address") { + if addr_type == "137" || acc.contact_address == "insert-address-token" { + acc.contact_address = address; + } + if acc.contact_address == "insert-address-token" { + acc.r#type = 4; + } + } + } + } + b"part" => { + let ct = attr_value(reader, &e, b"ct").unwrap_or_default(); + if ct == "text/plain" { + if let Some(text) = attr_value(reader, &e, b"text") { + acc.text_parts.push(text); + } + } else if !ct.is_empty() { + *acc.media_counts.entry(ct).or_insert(0) += 1; + } + } + _ => {} + } + } + Ok(Event::End(e)) => { + if e.local_name().as_ref() == b"mms" { + let bytes_read = reader.buffer_position() as u64; + return Ok((acc, bytes_read, parsed_count)); + } + } + Ok(Event::Eof) => { + return Err("Unexpected EOF while parsing ".to_string()); + } + Err(e) => { + return Err(format!("XML read error: {e}")); + } + _ => {} + } + + buf.clear(); + + } +} + +pub fn parse_sms_backup_streaming( + path: &Path, + mut emit_batch: FEmitBatch, + mut emit_progress: FEmitProgress, +) -> Result +where + FEmitBatch: FnMut(ParseBatch) -> Result<(), String>, + FEmitProgress: FnMut(ParseProgress) -> Result<(), String>, +{ + let file = File::open(path).map_err(|e| format!("Failed to open file: {e}"))?; + let total_bytes = file + .metadata() + .map(|m| m.len()) + .unwrap_or(0); + + let mut reader = Reader::from_reader(BufReader::new(file)); + reader.config_mut().trim_text(true); + + const BATCH_SIZE: usize = 500; + const PROGRESS_EVERY: u64 = 2_000; + + let mut parsed_count: u64 = 0; + let mut batch: Vec = Vec::with_capacity(BATCH_SIZE); + + let mut buf = Vec::new(); + loop { + match reader.read_event_into(&mut buf) { + Ok(Event::Empty(e)) => { + match e.local_name().as_ref() { + b"sms" => { + let contact_address = attr_value(&reader, &e, b"address").unwrap_or_default(); + let contact_name = attr_value(&reader, &e, b"contact_name"); + let msg_type = parse_i32(attr_value(&reader, &e, b"type"), 0); + let timestamp = attr_value(&reader, &e, b"date").unwrap_or_default(); + let date_ms = parse_i64(Some(timestamp.clone()), 0); + let body = attr_value(&reader, &e, b"body").unwrap_or_default(); + + batch.push(ParsedMessage { + contactAddress: contact_address, + contactName: contact_name, + r#type: msg_type, + timestamp, + dateMs: date_ms, + body, + }); + parsed_count += 1; + } + _ => {} + } + } + Ok(Event::Start(e)) => { + match e.local_name().as_ref() { + b"sms" => { + // Some exporters may use ... . Treat as start tag. + let contact_address = attr_value(&reader, &e, b"address").unwrap_or_default(); + let contact_name = attr_value(&reader, &e, b"contact_name"); + let msg_type = parse_i32(attr_value(&reader, &e, b"type"), 0); + let timestamp = attr_value(&reader, &e, b"date").unwrap_or_default(); + let date_ms = parse_i64(Some(timestamp.clone()), 0); + let body = attr_value(&reader, &e, b"body").unwrap_or_default(); + + batch.push(ParsedMessage { + contactAddress: contact_address, + contactName: contact_name, + r#type: msg_type, + timestamp, + dateMs: date_ms, + body, + }); + parsed_count += 1; + } + b"mms" => { + let contact_name = attr_value(&reader, &e, b"contact_name"); + let timestamp = attr_value(&reader, &e, b"date").unwrap_or_default(); + let date_ms = parse_i64(Some(timestamp.clone()), 0); + + let (acc, _bytes_read, parsed_so_far) = parse_mms_inner(&mut reader, parsed_count)?; + + let body = mms_body(&acc.text_parts, &acc.media_counts); + + batch.push(ParsedMessage { + contactAddress: acc.contact_address, + contactName: contact_name, + r#type: acc.r#type, + timestamp, + dateMs: date_ms, + body, + }); + parsed_count = parsed_so_far + 1; + } + _ => {} + } + } + Ok(Event::Eof) => break, + Err(e) => return Err(format!("XML read error: {e}")), + _ => {} + } + + buf.clear(); + + let bytes_read = reader.buffer_position() as u64; + + if !batch.is_empty() && batch.len() >= BATCH_SIZE { + emit_batch(ParseBatch { + messages: std::mem::take(&mut batch), + bytesRead: bytes_read, + totalBytes: total_bytes, + parsedCount: parsed_count, + })?; + } + + if parsed_count > 0 && parsed_count % PROGRESS_EVERY == 0 { + emit_progress(ParseProgress { + bytesRead: bytes_read, + totalBytes: total_bytes, + parsedCount: parsed_count, + })?; + } + } + + let bytes_read = reader.buffer_position() as u64; + + if !batch.is_empty() { + emit_batch(ParseBatch { + messages: std::mem::take(&mut batch), + bytesRead: bytes_read, + totalBytes: total_bytes, + parsedCount: parsed_count, + })?; + } + + emit_progress(ParseProgress { + bytesRead: bytes_read, + totalBytes: total_bytes, + parsedCount: parsed_count, + })?; + + Ok(ParseDone { + bytesRead: bytes_read, + totalBytes: total_bytes, + parsedCount: parsed_count, + }) +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json new file mode 100644 index 0000000..4c5b321 --- /dev/null +++ b/src-tauri/tauri.conf.json @@ -0,0 +1,38 @@ +{ + "$schema": "../node_modules/@tauri-apps/cli/config.schema.json", + "productName": "SMS Backup Viewer", + "version": "0.26.0", + "identifier": "io.github.smokehound.sms-backup-viewer", + "build": { + "frontendDist": "../dist/sms-backup-viewer/browser", + "devUrl": "http://localhost:4200", + "beforeDevCommand": "npm run start:tauri", + "beforeBuildCommand": "npm run build:tauri" + }, + "app": { + "windows": [ + { + "title": "SMS Backup Viewer", + "width": 1100, + "height": 700, + "resizable": true, + "maximized": true, + "fullscreen": false + } + ], + "security": { + "csp": null + } + }, + "bundle": { + "active": true, + "targets": "all", + "icon": [ + "icons/32x32.png", + "icons/128x128.png", + "icons/128x128@2x.png", + "icons/icon.icns", + "icons/icon.ico" + ] + } +} diff --git a/src/app/about-dialog/about-dialog.component.css b/src/app/about-dialog/about-dialog.component.css new file mode 100644 index 0000000..011771c --- /dev/null +++ b/src/app/about-dialog/about-dialog.component.css @@ -0,0 +1,5 @@ +.about-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.45); display:flex; align-items:center; justify-content:center; z-index: 1200; } +.about-modal { background: #fff; padding: 18px; border-radius: 8px; width: 420px; max-width: 94%; box-shadow: 0 10px 30px rgba(0,0,0,0.25); } +.about-modal h3 { margin-top: 0; } +.about-body { color: #333; font-size: 0.95rem; } +.about-actions { display:flex; gap: 10px; justify-content:flex-end; margin-top: 14px; } diff --git a/src/app/about-dialog/about-dialog.component.html b/src/app/about-dialog/about-dialog.component.html new file mode 100644 index 0000000..d1aa350 --- /dev/null +++ b/src/app/about-dialog/about-dialog.component.html @@ -0,0 +1,16 @@ +
+
+

About

+
+
SMS Backup Viewer
+
Version: v{{ version }}
+
Build time: {{ buildTimeLocal || buildTime }}
+
Commit: {{ commit }}
+

A small tool for inspecting and merging SMS backup XML files.

+
+
+ + +
+
+
\ No newline at end of file diff --git a/src/app/about-dialog/about-dialog.component.ts b/src/app/about-dialog/about-dialog.component.ts new file mode 100644 index 0000000..e01dfc8 --- /dev/null +++ b/src/app/about-dialog/about-dialog.component.ts @@ -0,0 +1,48 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; +import { CommonModule } from '@angular/common'; + +@Component({ + selector: 'app-about-dialog', + standalone: true, + imports: [CommonModule], + templateUrl: './about-dialog.component.html', + styleUrls: ['./about-dialog.component.css'] +}) +export class AboutDialogComponent { + @Input() version: string = ''; + @Input() buildTime: string = ''; + @Input() commit: string = ''; + @Output() close = new EventEmitter(); + + get buildTimeLocal(): string { + const raw = (this.buildTime || '').trim(); + if (!raw) { + return ''; + } + const d = new Date(raw); + if (!Number.isFinite(d.getTime())) { + return raw; + } + try { + return new Intl.DateTimeFormat(undefined, { + dateStyle: 'medium', + timeStyle: 'medium' + }).format(d); + } catch { + return d.toLocaleString(); + } + } + + onClose() { + this.close.emit(); + } + + copyInfo() { + try { + const text = `v${this.version} — built ${this.buildTimeLocal || this.buildTime}${this.commit ? ' — ' + this.commit : ''}`; + navigator.clipboard.writeText(text); + } catch { + // ignore + } + } +} \ No newline at end of file diff --git a/src/app/app.component.css b/src/app/app.component.css index e69de29..2598c1f 100644 --- a/src/app/app.component.css +++ b/src/app/app.component.css @@ -0,0 +1,276 @@ +/* App-level styles */ +.mdl-layout { + min-height: 100vh; + display: flex; + flex-direction: column; +} + +.mdl-layout__content { + flex: 1 1 auto; + min-height: 0; + display: flex; + flex-direction: column; +} + +.mdl-layout__header { + background: var(--surface); + color: var(--text); + box-shadow: none; + border-bottom: 1px solid var(--border); +} + +/* Responsive header tools (drawer removed) */ +.mdl-layout__header-row { + flex-wrap: wrap; + row-gap: 8px; + padding-left: 16px; + padding-right: 16px; +} + +.header-tools { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.header-tools .mdl-button { + margin: 0; +} + +.header-tools .material-icons { + font-size: 18px; +} + +.header-settings .material-icons { + margin-right: 8px; +} + +/* Header Settings button should be neutral (black), not accent-blue */ +.mdl-layout__header .header-settings, +.mdl-layout__header .header-settings .material-icons, +.mdl-layout__header .header-settings .settings-label { + color: var(--text) !important; +} + +@media (max-width: 640px) { + .mdl-layout-spacer { + display: none; + } + .mdl-layout-title { + flex: 1 1 100%; + } + .header-tools { + width: 100%; + gap: 6px; + } + + .mdl-layout__header .file-upload-button, + .mdl-layout__header .header-settings { + padding: 0 10px; + min-width: 40px; + } + + .mdl-layout__header .file-upload-button .material-icons, + .mdl-layout__header .header-settings .material-icons { + margin-right: 0; + } + + .mdl-layout__header .file-upload-label, + .mdl-layout__header .settings-label { + display: none; + } +} + +.mdl-layout-title { + cursor: pointer; + text-align: left; + transition: opacity 0.2s ease; +} + +.mdl-layout-title:hover { + opacity: 0.8; +} + +.mdl-navigation .mdl-button { + margin: 0 8px; +} + +.top-tools { + display: flex; + flex-wrap: wrap; + align-items: flex-start; + gap: 12px; + padding: 12px; + margin: 8px; + border-radius: 10px; + background: rgba(255, 255, 255, 0.75); + border: 1px solid rgba(0, 0, 0, 0.08); +} + +.top-tools .tool { + min-width: 220px; + flex: 1 1 320px; +} + +.top-tools .tool-settings { + flex: 0 0 auto; + min-width: auto; + display: flex; + align-items: flex-start; +} + +/* Footer improvements */ +.mdl-mini-footer { + background-color: #424242; + color: rgba(255, 255, 255, 0.87); + /* Reduce vertical padding only; keep font sizes unchanged */ + padding: 1px 8px; + min-height: 20px; + line-height: 1.05; + display: flex; + align-items: center; + justify-content: space-between; +} +.mdl-mini-footer__logo { + margin: 0; + font-size: 14px; /* restored to original size */ + line-height: 1.05; +} + +.mdl-mini-footer__left-section { + display: flex; + align-items: center; + gap: 6px; +} + +.mdl-mini-footer__right-section { + display: flex; + align-items: center; + gap: 6px; +} + +/* Compact loader controls when placed in the header nav/drawer */ +.mdl-layout__header .loader-inline, +.mdl-layout__drawer .loader-inline { + gap: 6px; +} + +/* Keep the Tauri path UI out of the header row */ +.mdl-layout__header app-sms-loader .tauri-tools { + display: none; +} + +.app-statusbar { + padding: 8px 16px; + background: var(--surface-2); + border-top: 1px solid var(--border); +} + +.app-statusbar-row { + display: flex; + align-items: center; + gap: 16px; + flex-wrap: wrap; +} + +.app-status-item { + display: flex; + align-items: center; + gap: 8px; + min-width: 280px; + flex: 1 1 320px; +} + +.app-status-item::before { + content: ''; + width: 10px; + height: 10px; + border-radius: 999px; + background: rgba(0, 0, 0, 0.35); +} + +.app-status-item.busy::before { + background: rgba(33, 150, 243, 0.95); +} + +.app-status-item.ok::before { + background: rgba(76, 175, 80, 0.95); +} + +.app-status-item.error::before { + background: rgba(244, 67, 54, 0.95); +} + +.app-status-label { + font-size: 12px; + font-weight: 600; + letter-spacing: 0.04em; + text-transform: uppercase; + opacity: 0.7; +} + +.app-status-text { + font-size: 13px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.app-statusbar-progress { + margin-top: 6px; + height: 4px; + border-radius: 999px; + overflow: hidden; + background: rgba(0, 0, 0, 0.12); +} + +.app-statusbar-progress-fill { + height: 100%; + background: rgba(33, 150, 243, 0.75); + width: 0%; + transition: width 120ms linear; +} + +.mdl-mini-footer .mdl-logo { + font-size: 12px; + line-height: 1.1; + padding: 0; + margin: 0; +} + +.mdl-mini-footer__link-list { + margin: 0; + display: flex; + gap: 8px; + align-items: center; +} + +.mdl-mini-footer__link-list li { + line-height: 1.1; + font-size: 12px; +} + +.footer-version { + font-size: 12px; /* restored to original readable size */ + opacity: 0.8; + white-space: nowrap; +} +/* Slimmer about button */ +.about-btn { margin-left: 8px; background: transparent; color: rgba(255,255,255,0.9); border: 1px solid rgba(255,255,255,0.06); padding: 2px 6px; border-radius: 4px; font-size: 11px; line-height: 1; } +.about-btn:hover { background: rgba(255,255,255,0.04) } + +/* Icon-only variant: visually an icon (no button chrome) */ +.about-btn--icon { padding: 4px; width: auto; height: auto; display: inline-flex; align-items: center; justify-content: center; border: none; background: transparent; min-width: 0; margin-left: 8px; cursor: pointer; } +.about-btn--icon .material-icons { font-size: 16px; line-height: 1; color: rgba(255,255,255,0.9); } +.about-btn--icon:hover { background: transparent; opacity: 0.95; } + +.mdl-mini-footer a { + color: rgba(255, 255, 255, 0.87); + text-decoration: none; + transition: color 0.2s ease; +} + +.mdl-mini-footer a:hover { + color: #03a9f4; +} diff --git a/src/app/app.component.html b/src/app/app.component.html index 993e90f..e3011c5 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -3,41 +3,64 @@
- SMS Backup Reader 2 + SMS Backup Viewer
-
-
- Menu - -
-
+
+
+
+ SMS + {{ smsStatus.text }} +
+
+ Contacts + {{ vcfStatus.text }} +
+
+
+
+
+
+ + +
+ diff --git a/src/app/app.component.spec.ts b/src/app/app.component.spec.ts index 36de47e..6542496 100644 --- a/src/app/app.component.spec.ts +++ b/src/app/app.component.spec.ts @@ -1,33 +1,32 @@ -/* tslint:disable:no-unused-variable */ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; -import { TestBed, async } from '@angular/core/testing'; import { AppComponent } from './app.component'; +import { SmsLoaderService } from './sms-loader.service'; +import { SmsStoreService } from './sms-store.service'; +import { VcfLoaderService } from './vcf-loader.service'; +import { VcfStoreService } from './vcf-store.service'; describe('AppComponent', () => { - beforeEach(() => { - TestBed.configureTestingModule({ - declarations: [ - AppComponent - ], - }); + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [AppComponent], + providers: [SmsStoreService, SmsLoaderService, VcfLoaderService, VcfStoreService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }).compileComponents(); }); - it('should create the app', async(() => { - let fixture = TestBed.createComponent(AppComponent); - let app = fixture.debugElement.componentInstance; + it('should create the app', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; expect(app).toBeTruthy(); - })); - - it(`should have as title 'app works!'`, async(() => { - let fixture = TestBed.createComponent(AppComponent); - let app = fixture.debugElement.componentInstance; - expect(app.title).toEqual('app works!'); - })); + }); - it('should render title in a h1 tag', async(() => { - let fixture = TestBed.createComponent(AppComponent); - fixture.detectChanges(); - let compiled = fixture.debugElement.nativeElement; - expect(compiled.querySelector('h1').textContent).toContain('app works!'); - })); + it('should have the expected title', () => { + const fixture = TestBed.createComponent(AppComponent); + const app = fixture.componentInstance; + expect(app.title).toEqual('SMS Backup Viewer'); + }); }); diff --git a/src/app/app.component.ts b/src/app/app.component.ts index 8fdf68e..f80b6e3 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, HostListener } from '@angular/core'; import { SmsLoaderComponent } from './sms-loader/sms-loader.component'; import { VcfLoaderComponent } from './vcf-loader/vcf-loader.component'; @@ -7,61 +7,180 @@ import { SmsStoreService } from './sms-store.service'; import { SmsLoaderService } from './sms-loader.service'; import { VcfLoaderService } from './vcf-loader.service'; import { VcfStoreService } from './vcf-store.service'; -var URLSearchParams = require('url-search-params'); -const { version: appVersion } = require('../../package.json'); +import { LoaderStatusUpdate } from './loader-status'; +import { APP_VERSION, APP_BUILD_TIME, APP_GIT_COMMIT } from './version'; +import { LogService } from './log.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', - styleUrls: ['./app.component.css'] + styleUrls: ['./app.component.css'], + standalone: false }) export class AppComponent implements OnInit { - title = 'SMS Backup Reader 2.0'; + title = 'SMS Backup Viewer'; + appVersion = APP_VERSION; + appBuildTime = APP_BUILD_TIME; + appGitCommit = (typeof APP_GIT_COMMIT !== 'undefined') ? APP_GIT_COMMIT : ''; + get appVersionTooltip(): string { + let t = `v${this.appVersion} — built ${this.appBuildTime}`; + if (this.appGitCommit) { + t += ` — ${this.appGitCommit}`; + } + return t; + } + + // About dialog control + showAbout: boolean = false; + openAbout() { this.showAbout = true; } + closeAbout() { this.showAbout = false; } + + @HostListener('window:keydown', ['$event']) + handleKeyDown(event: KeyboardEvent) { + const isMac = (navigator.platform || '').toLowerCase().includes('mac'); + const mod = isMac ? event.metaKey : event.ctrlKey; + if (mod && (event.key === 'i' || event.key === 'I')) { + event.preventDefault(); + this.openAbout(); + } + } smsloaded: boolean = false; vcfloaded: boolean = false; - private appVersion; - country: string = "US"; + country: string = "AU"; + + smsStatus: LoaderStatusUpdate = { + source: 'sms', + status: 'idle', + text: 'not loaded', + updatedAt: 0 + }; + + vcfStatus: LoaderStatusUpdate = { + source: 'vcf', + status: 'idle', + text: 'not loaded', + updatedAt: 0 + }; constructor(private smsStoreService: SmsStoreService, private smsLoaderService: SmsLoaderService, private vcfLoaderService: VcfLoaderService, - private vcfStoreService: VcfStoreService) + private vcfStoreService: VcfStoreService, + private logs: LogService) { - this.appVersion = appVersion; } private getQueryParameter(key: string): string { const parameters = new URLSearchParams(window.location.search); return parameters.get(key); } ngOnInit() { - if (this.getQueryParameter('country')) { - this.country = this.getQueryParameter('country'); + this.logs.info('App started', { + version: this.appVersion, + buildTime: this.appBuildTime, + commit: this.appGitCommit || undefined + }); + + // Apply default country on startup. + this.smsStoreService.changeCountry(this.country); + this.vcfStoreService.changeCountry(this.country); + + // URL override (e.g. ?country=US) + const qpCountry = this.getQueryParameter('country'); + if (qpCountry) { + this.country = qpCountry; this.smsStoreService.changeCountry(this.country); this.vcfStoreService.changeCountry(this.country); - console.log(this.getQueryParameter('country')); + this.logs.info('Country override applied', { country: this.country }); + } + + // If there's persisted data (IndexedDB mode), restore it on startup. + this.smsStoreService + .restoreFromIndexedDbIfEnabled() + .then((restored) => { + if (restored) { + this.logs.info('Restored messages from IndexedDB'); + this.smsloaded = true; + this.smsStoreService.broadcastMessagesLoaded(true); + } + }) + .catch((e) => { + this.logs.error('Failed to restore from IndexedDB', e); + }); + } + + onSmsStatusChanged(update: LoaderStatusUpdate): void { + const prev = this.smsStatus; + const next = this.mergeStatus(this.smsStatus, update, 'sms'); + this.smsStatus = next; + this.logStatusTransition('SMS', prev, next); + } + + onVcfStatusChanged(update: LoaderStatusUpdate): void { + const prev = this.vcfStatus; + const next = this.mergeStatus(this.vcfStatus, update, 'vcf'); + this.vcfStatus = next; + this.logStatusTransition('Contacts', prev, next); + } + + private logStatusTransition(label: string, prev: LoaderStatusUpdate, next: LoaderStatusUpdate): void { + if (!next) return; + const changed = prev?.status !== next.status || prev?.text !== next.text; + if (!changed) return; + + const msg = `[${label}] ${next.text || next.status}`; + switch (next.status) { + case 'error': + this.logs.error(msg, next); + break; + case 'ok': + this.logs.info(msg, next); + break; + case 'busy': + this.logs.debug(msg, next); + break; + default: + this.logs.debug(msg, next); + break; + } + } + + private mergeStatus( + current: LoaderStatusUpdate, + incoming: LoaderStatusUpdate, + expectedSource: 'sms' | 'vcf' + ): LoaderStatusUpdate { + if (!incoming || incoming.source !== expectedSource) { + return current; } + // Prefer newest update; fall back to current if timestamps are missing. + const currentAt = current?.updatedAt ?? 0; + const incomingAt = incoming?.updatedAt ?? 0; + if (incomingAt < currentAt) { + return current; + } + return incoming; } onSmsLoaded(loaded: boolean) { - console.log('Event emit!'); if (loaded) { + this.logs.info('SMS import completed'); if (this.smsloaded) { - console.log('Clear then load :)'); this.smsloaded = false; this.smsStoreService.clearAllMessages().then(() => { - this.loadMessages(loaded); + this.loadMessages(loaded); }); } else { - this.loadMessages(loaded); + this.loadMessages(loaded); } } } onVcfLoaded(loaded: boolean) { - console.log('Event emit!'); + if (loaded) { + this.logs.info('Contacts import completed'); + } if (this.vcfloaded) { - console.log('Clear then load :)'); this.vcfloaded = false; this.vcfStoreService.clearAllContacts().then(() => { this.loadContacts(loaded); @@ -74,23 +193,38 @@ export class AppComponent implements OnInit { private loadMessages(loaded: boolean): void { - this.smsLoaderService.getLoadedMessages().then(messages => { - this.smsStoreService.loadAllMessages(messages).then(() => { - this.smsloaded = loaded; - if ((this.vcfloaded)&& - (loaded)) - { - this.vcfStoreService.getAllContacts().then(contactsMap => { + // If a Tauri streaming load already populated the store, don't re-load from SmsLoaderService. + if (this.smsStoreService.messagesLoaded) { + this.smsloaded = loaded; + if (this.vcfloaded && loaded) { + this.vcfStoreService.getAllContacts().then((contactsMap) => { + this.smsStoreService.fillContactNames(contactsMap); + this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); + }); + } + if (loaded) { + this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); + } + return; + } + + this.smsLoaderService.getLoadedMessages().then((messages) => { + if (!messages?.length) { + return; + } + this.smsStoreService.loadAllMessages(messages).then(() => { + this.smsloaded = loaded; + if (this.vcfloaded && loaded) { + this.vcfStoreService.getAllContacts().then((contactsMap) => { this.smsStoreService.fillContactNames(contactsMap); - this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); + this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); }); } - if (loaded) - { - this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); + if (loaded) { + this.smsStoreService.broadcastMessagesLoaded(this.smsloaded); } - }); - }); + }); + }); } private loadContacts(loaded: boolean): void { diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 5e6c71a..cd340d7 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -1,27 +1,36 @@ import { BrowserModule } from '@angular/platform-browser'; -import { NgModule } from '@angular/core'; +import { NgModule, provideBrowserGlobalErrorListeners } from '@angular/core'; import { FormsModule, ReactiveFormsModule } from '@angular/forms'; -import { HttpModule } from '@angular/http'; import { RouterModule, Routes } from '@angular/router'; import { AppComponent } from './app.component'; +import { ScrollingModule } from '@angular/cdk/scrolling'; import { SmsLoaderComponent } from './sms-loader/sms-loader.component'; import { ContactListComponent } from './contact-list/contact-list.component'; import { MessageListComponent } from './message-list/message-list.component'; +import { ExportOptionsDialogComponent } from './message-list/export-options-dialog.component'; import { SmsStoreService } from './sms-store.service'; import { SmsLoaderService } from './sms-loader.service'; import { VcfLoaderService } from './vcf-loader.service'; import { VcfStoreService } from './vcf-store.service'; +import { SmsDbService } from './sms-db.service'; import { CountrySelectComponent } from './country-select/country-select.component'; +import { LazyInnerHtmlDirective } from './directives/lazy-inner-html.directive'; import { MessageTypePipe } from './message-type.pipe'; import { MainComponent } from './main/main.component'; import { SettingsComponent } from './settings/settings.component'; import { VcfLoaderComponent } from './vcf-loader/vcf-loader.component'; -import {ContactSearchPipe} from './components/pipes/contact-search-pipe'; +import { ContactSearchPipe } from './components/pipes/contact-search-pipe'; +import { JoinBackupsComponent } from './join-backups/join-backups.component'; +import { ToastComponent } from './toast.component'; +import { AboutDialogComponent } from './about-dialog/about-dialog.component'; +import { LogComponent } from './log/log.component'; const appRoutes: Routes = [ { path: 'main', component: MainComponent }, { path: 'settings', component: SettingsComponent }, +{ path: 'tools/join-backups', component: JoinBackupsComponent }, +{ path: 'log', component: LogComponent }, { path: '', redirectTo: '/main', pathMatch: 'full' @@ -33,6 +42,7 @@ pathMatch: 'full' SmsLoaderComponent, ContactListComponent, MessageListComponent, + ExportOptionsDialogComponent, CountrySelectComponent, MessageTypePipe, MainComponent, @@ -43,10 +53,24 @@ pathMatch: 'full' imports: [ BrowserModule, FormsModule, - HttpModule, - RouterModule.forRoot(appRoutes) + RouterModule.forRoot(appRoutes), + ScrollingModule, + LazyInnerHtmlDirective, + // include standalone components + JoinBackupsComponent, + LogComponent, + ToastComponent, + // About dialog (standalone) + AboutDialogComponent + ], + providers: [ + provideBrowserGlobalErrorListeners(), + SmsStoreService, + SmsDbService, + SmsLoaderService, + VcfLoaderService, + VcfStoreService ], - providers: [SmsStoreService, SmsLoaderService, VcfLoaderService, VcfStoreService], bootstrap: [AppComponent] }) export class AppModule { } diff --git a/src/app/components/pipes/contact-search-pipe.ts b/src/app/components/pipes/contact-search-pipe.ts index b70cbff..61c3a26 100644 --- a/src/app/components/pipes/contact-search-pipe.ts +++ b/src/app/components/pipes/contact-search-pipe.ts @@ -2,7 +2,8 @@ import { PipeTransform, Pipe } from '@angular/core'; import { Contact } from '../../contact'; @Pipe({ name: 'contactSearchPipe', - pure: true + pure: true, + standalone: false }) export class ContactSearchPipe implements PipeTransform { transform(data: Contact[], searchTerm: string): any[] { diff --git a/src/app/contact-list/contact-list.component.css b/src/app/contact-list/contact-list.component.css index 26f6030..b5cf76c 100644 --- a/src/app/contact-list/contact-list.component.css +++ b/src/app/contact-list/contact-list.component.css @@ -1,13 +1,51 @@ .demo-list-two { - /*width: 300px;*/ + padding: 6px; + margin: 0; +} + +.contact-list-header { + padding: 14px 14px 10px; + background: var(--surface); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 10; + border-top-left-radius: var(--radius); + border-top-right-radius: var(--radius); +} + +.contact-filter { + width: 100%; } .contact-item { cursor: pointer; - cursor: hand; + border: 1px solid transparent; + border-radius: 12px; + margin: 4px 6px; + transition: background-color 0.15s ease, border-color 0.15s ease, transform 0.12s ease; +} + +.contact-item:hover { + background-color: rgba(37, 99, 235, 0.06); + border-color: rgba(37, 99, 235, 0.10); +} + +.contact-item .mdl-list__item-primary-content { + padding-left: 8px; +} + +.active-row { + background-color: var(--primary-weak) !important; + border-color: rgba(37, 99, 235, 0.20); +} + +.contact-title { + font-weight: 600; } -.active-row{ - background-color: #0099ff; +.contact-subtitle { + font-size: 12px; + color: var(--muted); } diff --git a/src/app/contact-list/contact-list.component.html b/src/app/contact-list/contact-list.component.html index dd9b99a..3ace471 100644 --- a/src/app/contact-list/contact-list.component.html +++ b/src/app/contact-list/contact-list.component.html @@ -1,12 +1,19 @@
- Filter Contacts: +
+
+ + +
+
  • + *ngFor="let contact of contacts | contactSearchPipe: numfilter; trackBy: trackByContact" (click)="showMessages(contact)" [ngClass]="{'active-row': contact == selectedContact}"> - person - Address: {{contact.address}}
    {{contact.name}}
    - Messages: {{contact.messageCount}} + + {{contact.name || contact.address}} +
    {{contact.address}}
    +
    + {{contact.messageCount}} messages
diff --git a/src/app/contact-list/contact-list.component.spec.ts b/src/app/contact-list/contact-list.component.spec.ts index 205b91d..d802c4a 100644 --- a/src/app/contact-list/contact-list.component.spec.ts +++ b/src/app/contact-list/contact-list.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; import { ContactListComponent } from './contact-list.component'; +import { ContactSearchPipe } from '../components/pipes/contact-search-pipe'; +import { SmsStoreService } from '../sms-store.service'; describe('ContactListComponent', () => { let component: ContactListComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ ContactListComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FormsModule], + declarations: [ ContactListComponent, ContactSearchPipe ], + providers: [SmsStoreService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(ContactListComponent); diff --git a/src/app/contact-list/contact-list.component.ts b/src/app/contact-list/contact-list.component.ts index 4e13500..a32a5f5 100644 --- a/src/app/contact-list/contact-list.component.ts +++ b/src/app/contact-list/contact-list.component.ts @@ -1,5 +1,5 @@ -import { Component, OnInit } from '@angular/core'; -import {Subscription} from 'rxjs/Subscription'; +import { Component, OnInit, NgZone } from '@angular/core'; +import { Subscription } from 'rxjs'; import { Message } from '../message'; import { Contact } from '../contact'; @@ -9,6 +9,7 @@ import { SmsStoreService } from '../sms-store.service'; selector: 'contact-list', templateUrl: './contact-list.component.html', styleUrls: ['./contact-list.component.css'], + standalone: false }) export class ContactListComponent implements OnInit { @@ -20,7 +21,7 @@ export class ContactListComponent implements OnInit { numfilter: string - constructor(private smsStoreService: SmsStoreService) { } + constructor(private smsStoreService: SmsStoreService, private ngZone: NgZone) { } ngOnInit() { this.numfilter = ''; @@ -33,7 +34,12 @@ export class ContactListComponent implements OnInit { } getAllContacts() { - this.smsStoreService.getAllContacts().then((contacts) => this.contacts = contacts); + this.smsStoreService.getAllContacts().then((contacts) => { + // Dexie/IndexedDB promises can resolve outside Angular's zone. + this.ngZone.run(() => { + this.contacts = contacts; + }); + }); } showMessages(contact) { @@ -41,6 +47,10 @@ export class ContactListComponent implements OnInit { this.smsStoreService.broadcastContactClicked(contact); } + trackByContact(_index: number, contact: Contact): string { + return contact?.address; + } + isSelected(contact) { return(this.selectedContact == contact); } diff --git a/src/app/country-select/country-select.component.css b/src/app/country-select/country-select.component.css index 76585d8..848b8c0 100644 --- a/src/app/country-select/country-select.component.css +++ b/src/app/country-select/country-select.component.css @@ -1,6 +1,25 @@ -select { - padding: 10px; - margin-left: auto; - margin-right: auto; - margin-bottom: 10px; -} \ No newline at end of file +.country-select-container { + width: 100%; +} + +.country-select-dropdown { + width: 100%; + padding: 12px 16px; + font-size: 14px; + border: 1px solid #ddd; + border-radius: 4px; + background-color: white; + cursor: pointer; + transition: border-color 0.2s ease, box-shadow 0.2s ease; + font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; +} + +.country-select-dropdown:hover { + border-color: #03a9f4; +} + +.country-select-dropdown:focus { + outline: none; + border-color: #03a9f4; + box-shadow: 0 0 0 2px rgba(3, 169, 244, 0.1); +} diff --git a/src/app/country-select/country-select.component.html b/src/app/country-select/country-select.component.html index 067b9e7..19d9270 100644 --- a/src/app/country-select/country-select.component.html +++ b/src/app/country-select/country-select.component.html @@ -1,5 +1,5 @@ -
-
\ No newline at end of file diff --git a/src/app/country-select/country-select.component.spec.ts b/src/app/country-select/country-select.component.spec.ts index 1b32d86..2c1aac0 100644 --- a/src/app/country-select/country-select.component.spec.ts +++ b/src/app/country-select/country-select.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; import { CountrySelectComponent } from './country-select.component'; +import { SmsStoreService } from '../sms-store.service'; +import { VcfStoreService } from '../vcf-store.service'; describe('CountrySelectComponent', () => { let component: CountrySelectComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ CountrySelectComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FormsModule], + declarations: [ CountrySelectComponent ], + providers: [SmsStoreService, VcfStoreService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(CountrySelectComponent); diff --git a/src/app/country-select/country-select.component.ts b/src/app/country-select/country-select.component.ts index 87d12d5..b73c769 100644 --- a/src/app/country-select/country-select.component.ts +++ b/src/app/country-select/country-select.component.ts @@ -5,7 +5,8 @@ import { VcfStoreService } from '../vcf-store.service'; @Component({ selector: 'country-select', templateUrl: './country-select.component.html', - styleUrls: ['./country-select.component.css'] + styleUrls: ['./country-select.component.css'], + standalone: false }) export class CountrySelectComponent implements OnInit { @@ -119,7 +120,7 @@ export class CountrySelectComponent implements OnInit { { "value": "HU", "label": "Hungary" }, { "value": "IS", "label": "Iceland" }, { "value": "IN", "label": "India" }, - { "value": "value", "label": "Indonesia" }, + { "value": "ID", "label": "Indonesia" }, { "value": "IR", "label": "Iran (Islamic Republic of)" }, { "value": "IQ", "label": "Iraq" }, { "value": "IE", "label": "Ireland" }, @@ -272,12 +273,18 @@ export class CountrySelectComponent implements OnInit { } changeCountry(selectEvent: any): void { - console.log(`Country selected: ${selectEvent.target.value}`); this.vcfStoreService.changeCountry(selectEvent.target.value); - this.smsStoreService.changeCountry(selectEvent.target.value); - this.vcfStoreService.getAllContacts().then(contactsMap => { - this.smsStoreService.fillContactNames(contactsMap); - this.smsStoreService.broadcastMessagesLoaded(true); + this.smsStoreService.changeCountry(selectEvent.target.value).then(() => { + // Only fill contact names if both messages and contacts are loaded + this.vcfStoreService.areContactsLoaded().then(contactsLoaded => { + this.smsStoreService.areMessagesLoaded().then(messagesLoaded => { + if (contactsLoaded && messagesLoaded) { + this.vcfStoreService.getAllContacts().then(contactsMap => { + this.smsStoreService.fillContactNames(contactsMap); + }); + } + }); + }); }); } diff --git a/src/app/csv-export.service.spec.ts b/src/app/csv-export.service.spec.ts new file mode 100644 index 0000000..295fe24 --- /dev/null +++ b/src/app/csv-export.service.spec.ts @@ -0,0 +1,27 @@ +import { CsvExportService } from './csv-export.service'; + +describe('CsvExportService (media extraction)', () => { + it('extractInlineBase64MediaFromHtml should replace data URLs and return files', () => { + const svc = new CsvExportService(); + const html = + '
Hello
' + + '' + + '
World
'; + + const res = svc.extractInlineBase64MediaFromHtml(html, { + conversationId: '+15551234567', + messageIndex: 0, + timestampMs: 1700000000000, + baseDir: 'media' + }); + + expect(res.files.length).toBe(1); + expect(res.files[0].mime).toBe('image/jpeg'); + expect(res.files[0].path).toContain('media/'); + expect(res.files[0].path).toContain('.jpg'); + expect(res.files[0].bytes.length).toBeGreaterThan(0); + expect(res.html).toContain(`src="${res.files[0].path}"`); + // no remaining data URLs + expect(res.html).not.toContain('data:image/jpeg;base64'); + }); +}); diff --git a/src/app/csv-export.service.ts b/src/app/csv-export.service.ts new file mode 100644 index 0000000..3e4da30 --- /dev/null +++ b/src/app/csv-export.service.ts @@ -0,0 +1,260 @@ +import { Injectable } from '@angular/core'; +import { CsvCell, rowsToCsv } from './csv'; +import { ToastService } from './toast.service'; + +@Injectable({ + providedIn: 'root' +}) +export class CsvExportService { + constructor(private toastService: ToastService) {} + + private sanitizeFilename(name: string): string { + // Keep it Windows-friendly and avoid weird path characters. + return name.replace(/[\\/:*?"<>|]+/g, '_').trim(); + } + + private decodeBase64ToBytes(base64: string): Uint8Array { + // Browser: atob. Tests (node/jsdom): Buffer fallback. + if (typeof atob === 'function') { + const binary = atob(base64); + const bytes = new Uint8Array(binary.length); + for (let i = 0; i < binary.length; i++) { + bytes[i] = binary.charCodeAt(i); + } + return bytes; + } + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const buf = (globalThis as any)?.Buffer?.from?.(base64, 'base64'); + return buf ? new Uint8Array(buf) : new Uint8Array(); + } + + private mimeToExtension(mime: string): string { + const m = (mime || '').toLowerCase(); + if (m === 'image/jpeg' || m === 'image/jpg') return 'jpg'; + if (m === 'image/png') return 'png'; + if (m === 'image/gif') return 'gif'; + if (m === 'image/webp') return 'webp'; + if (m === 'video/mp4') return 'mp4'; + if (m === 'audio/mpeg') return 'mp3'; + if (m === 'audio/mp4') return 'm4a'; + return 'bin'; + } + + extractInlineBase64MediaFromHtml( + html: string, + options: { + conversationId: string; + messageIndex: number; + timestampMs?: number; + baseDir?: string; + } + ): { html: string; files: Array<{ path: string; bytes: Uint8Array; mime: string }> } { + if (!html) { + return { html: '', files: [] }; + } + + const baseDir = (options.baseDir ?? 'media').replace(/\\/g, '/').replace(/\/+$/g, ''); + const safeConversation = this.sanitizeFilename(options.conversationId || 'conversation'); + const timestampPart = Number.isFinite(options.timestampMs) ? String(options.timestampMs) : 'no-ts'; + const dir = `${baseDir}/${safeConversation}`; + + const files: Array<{ path: string; bytes: Uint8Array; mime: string }> = []; + + // DOM-based parsing is more reliable than regex for HTML. + const doc = new DOMParser().parseFromString(html, 'text/html'); + const images = Array.from(doc.querySelectorAll('img')); + + let imageIndex = 0; + for (const img of images) { + const src = img.getAttribute('src') ?? ''; + if (!src.startsWith('data:')) { + continue; + } + + const base64Marker = ';base64,'; + const markerIndex = src.indexOf(base64Marker); + if (markerIndex === -1) { + continue; + } + + const mime = src.slice('data:'.length, markerIndex).split(';')[0].trim(); + const base64 = src.slice(markerIndex + base64Marker.length); + const bytes = this.decodeBase64ToBytes(base64); + const ext = this.mimeToExtension(mime); + + const filename = `${timestampPart}-${options.messageIndex}-${imageIndex}.${ext}`; + const relPath = `${dir}/${filename}`; + + files.push({ path: relPath, bytes, mime }); + img.setAttribute('src', relPath); + imageIndex++; + } + + return { html: doc.body.innerHTML, files }; + } + + htmlToText(html: string): string { + if (!html) { + return ''; + } + + // Preserve something meaningful for embedded images and basic line breaks. + let text = html + .replace(/]*>/gi, '[image]') + .replace(/<(br\s*\/?>)/gi, '\n') + .replace(/<\/(div|p)>/gi, '\n'); + + // Strip any remaining tags. + text = text.replace(/<[^>]*>/g, ''); + + // Normalize whitespace/newlines for CSV consumption. + text = text.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + text = text.replace(/\n{3,}/g, '\n\n'); + return text.trim(); + } + + async downloadCsv( + filenameBase: string, + rows: Array>, + columns: string[] + ): Promise { + const filename = this.sanitizeFilename(filenameBase || 'export') + '.csv'; + + // Add BOM for better Excel UTF-8 handling. + const csv = '\ufeff' + rowsToCsv(rows, columns); + const blob = new Blob([csv], { type: 'text/csv;charset=utf-8' }); + + // Try Tauri-native save first when available. + if (this.isTauriRuntime()) { + try { + const savedPath = await this.tryTauriSaveBlob(filename, blob); + if (savedPath) { + // Show toast with action to open the folder + const dir = (savedPath || '').replace(/[/\\][^/\\]+$/, ''); + this.toastService.showWithAction( + `Saved to: ${savedPath}`, + 'Open folder', + async () => { + // Attempt to open the folder using Tauri shell if available. + await this.openFolder(dir); + }, + 7000 + ); + return; + } + } catch (e) { + console.warn('Tauri save failed, falling back to browser download', e); + } + } + + // Fallback: browser download + const url = URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = url; + link.download = filename; + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + link.remove(); + URL.revokeObjectURL(url); + } + + async downloadZip( + filenameBase: string, + files: Array<{ path: string; content: string | Uint8Array }> + ): Promise { + const filename = this.sanitizeFilename(filenameBase || 'export') + '.zip'; + const JSZip = (await import('jszip')).default; + const zip = new JSZip(); + + for (const f of files) { + const path = (f.path || '').replace(/\\/g, '/'); + zip.file(path, f.content as any); + } + + const blob = await zip.generateAsync({ type: 'blob' }); + + // Try Tauri-native save first when available. + if (this.isTauriRuntime()) { + try { + const savedPath = await this.tryTauriSaveBlob(filename, blob); + if (savedPath) { + const dir = (savedPath || '').replace(/[/\\][^/\\]+$/, ''); + this.toastService.showWithAction( + `Saved to: ${savedPath}`, + 'Open folder', + async () => { + // Attempt to open the folder using Tauri shell if available. + await this.openFolder(dir); + }, + 7000 + ); + return; + } + } catch (e) { + console.warn('Tauri save failed, falling back to browser download', e); + } + } + + // Fallback: browser download + const url = URL.createObjectURL(blob); + + const link = document.createElement('a'); + link.href = url; + link.download = filename; + link.style.display = 'none'; + document.body.appendChild(link); + link.click(); + link.remove(); + URL.revokeObjectURL(url); + } + + private async openFolder(dir: string): Promise { + try { + // Assemble import path at runtime so Vite does not try to resolve it for browser builds. + const shellPath = '@tauri-apps/api/' + 'shell'; + const { open } = await import(/* @vite-ignore */ shellPath) as any; + await open(dir); + } catch (e) { + // non-fatal; caller will handle user-visible messages. + console.warn('Failed to open folder', e); + } + } + + private isTauriRuntime(): boolean { + try { + const protocol = (window?.location?.protocol ?? '').toLowerCase(); + if (protocol === 'tauri:' || protocol === 'asset:') return true; + const host = (window?.location?.hostname ?? '').toLowerCase(); + if (host === 'tauri.localhost' || host.endsWith('.tauri.localhost')) return true; + const w = window as any; + if (typeof w?.__TAURI__ !== 'undefined' || typeof w?.__TAURI_INTERNALS__ !== 'undefined') return true; + return (navigator?.userAgent ?? '').toLowerCase().includes('tauri'); + } catch { + return false; + } + } + + private async tryTauriSaveBlob(filename: string, blob: Blob): Promise { + try { + const { save } = await import('@tauri-apps/plugin-dialog') as any; + const path = await save({ defaultPath: filename }); + if (!path) return null; + + const arrayBuffer = await blob.arrayBuffer(); + const uint8 = new Uint8Array(arrayBuffer); + const { writeFile } = await import('@tauri-apps/plugin-fs') as any; + await writeFile(path, uint8); + return path; + } catch (e) { + console.error('Tauri save error', e); + return null; + } + } + + buildCsv(rows: Array>, columns: string[]): string { + // Add BOM for better Excel UTF-8 handling. + return '\ufeff' + rowsToCsv(rows, columns); + } +} diff --git a/src/app/csv.spec.ts b/src/app/csv.spec.ts new file mode 100644 index 0000000..ffe756b --- /dev/null +++ b/src/app/csv.spec.ts @@ -0,0 +1,23 @@ +import { describe, expect, it } from 'vitest'; +import { escapeCsvCell, rowsToCsv } from './csv'; + +describe('csv utilities', () => { + it('escapes commas, quotes, and newlines', () => { + expect(escapeCsvCell('simple')).toBe('simple'); + expect(escapeCsvCell('a,b')).toBe('"a,b"'); + expect(escapeCsvCell('a"b')).toBe('"a""b"'); + expect(escapeCsvCell('a\n b')).toBe('"a\n b"'); + }); + + it('renders rows with header and CRLF', () => { + const csv = rowsToCsv( + [ + { colA: 'x', colB: 'y' }, + { colA: '1,2', colB: '3' } + ], + ['colA', 'colB'] + ); + + expect(csv).toBe('colA,colB\r\nx,y\r\n"1,2",3\r\n'); + }); +}); diff --git a/src/app/csv.ts b/src/app/csv.ts new file mode 100644 index 0000000..9588086 --- /dev/null +++ b/src/app/csv.ts @@ -0,0 +1,28 @@ +export type CsvCell = string | number | boolean | Date | null | undefined; + +export function formatCsvCell(value: CsvCell): string { + if (value === null || value === undefined) { + return ''; + } + if (value instanceof Date) { + return value.toISOString(); + } + return String(value); +} + +export function escapeCsvCell(value: CsvCell): string { + const text = formatCsvCell(value); + + const needsQuotes = /[\r\n,"]/g.test(text); + const escaped = text.replace(/"/g, '""'); + return needsQuotes ? `"${escaped}"` : escaped; +} + +export function rowsToCsv( + rows: Array>, + columns: string[] +): string { + const header = columns.map((c) => escapeCsvCell(c)).join(','); + const lines = rows.map((row) => columns.map((c) => escapeCsvCell(row[c])).join(',')); + return [header, ...lines].join('\r\n') + '\r\n'; +} diff --git a/src/app/directives/lazy-inner-html.directive.ts b/src/app/directives/lazy-inner-html.directive.ts new file mode 100644 index 0000000..815bbfa --- /dev/null +++ b/src/app/directives/lazy-inner-html.directive.ts @@ -0,0 +1,45 @@ +import { Directive, ElementRef, Input, OnInit, OnDestroy, Renderer2 } from '@angular/core'; + +@Directive({ selector: '[lazyInnerHtml]', standalone: true }) +export class LazyInnerHtmlDirective implements OnInit, OnDestroy { + @Input('lazyInnerHtml') html: string | null = null; + private observer: IntersectionObserver | null = null; + + constructor(private el: ElementRef, private renderer: Renderer2) {} + + ngOnInit(): void { + const root = this.findScrollParent(this.el.nativeElement); + this.observer = new IntersectionObserver((entries) => { + for (const entry of entries) { + if (entry.isIntersecting) { + this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.html ?? ''); + if (this.observer) { + this.observer.disconnect(); + this.observer = null; + } + break; + } + } + }, { root, rootMargin: '200px' }); + + this.observer.observe(this.el.nativeElement); + } + + ngOnDestroy(): void { + this.observer?.disconnect(); + this.observer = null; + } + + private findScrollParent(el: HTMLElement | null): HTMLElement | null { + let node: HTMLElement | null = el?.parentElement ?? null; + while (node) { + const style = window.getComputedStyle(node); + const overflowY = style.overflowY; + if (node.classList.contains('message-viewport') || overflowY === 'auto' || overflowY === 'scroll') { + return node; + } + node = node.parentElement; + } + return null; + } +} diff --git a/src/app/join-backups/join-backups.component.css b/src/app/join-backups/join-backups.component.css new file mode 100644 index 0000000..92b46e0 --- /dev/null +++ b/src/app/join-backups/join-backups.component.css @@ -0,0 +1,76 @@ +:host { + display: block; + padding: 14px 16px; +} + +.join-card { + padding: 18px; + border: 1px solid #e6e6e6; + border-radius: 12px; + max-width: 920px; + background: #fff; + margin: 0 auto; +} +.join-header { display:flex; align-items:center; gap: 10px; margin-bottom: 6px; } +.join-header h2 { margin: 0; font-weight: 600; } +.join-header-spacer { flex: 1 1 auto; } +.join-subtitle { color: #555; margin: 0 0 14px; } + +.controls { display:flex; flex-wrap: wrap; gap: 8px; align-items:center; margin-bottom: 12px; } + +/* Use label as the visible button */ +#fileInput { + display: none; +} + +.jb-btn { + background: #f8fafc; + border: 1px solid #cbd5e1; + padding: 8px 12px; + border-radius: 10px; + cursor: pointer; + font: inherit; + color: #0f172a; + line-height: 1; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + text-decoration: none; +} + +.jb-btn:hover { background: #f1f5f9; } +.jb-btn:disabled { opacity: 0.6; cursor: not-allowed; } + +.jb-btn--primary { + background: #2563eb; + border-color: #2563eb; + color: white; +} +.jb-btn--primary:hover { background: #1d4ed8; } + +.jb-btn--sm { padding: 6px 10px; border-radius: 9px; font-size: 0.95em; } + +.preview { display:flex; flex-wrap: wrap; gap:12px; margin-bottom:12px; color:#333 } +.preview > div { background: #f8fafc; border: 1px solid #e6e6e6; border-radius: 10px; padding: 8px 10px; } + +.file-list { margin-top: 8px; } +.file-list-title { margin: 8px 0; font-weight: 600; } +.file-list-empty { color:#555; font-size:0.95em; padding: 6px 0; } +.file-list ul { list-style: none; margin:0; padding: 0 } +.file-list li { padding: 10px 0; border-bottom: 1px solid #eef2f7; } +.file-list li:last-child { border-bottom: none; } +.status { margin-top:12px; color:#555 } +.file-bad { color: #b91c1c; margin-left: 8px; font-size: 0.9em; display: inline-flex; gap: 6px; align-items: center; } +.file-bad-msg { color: #7f1d1d; font-size: 0.8em; margin-left: 6px; } +.file-line { display:flex; justify-content:space-between; align-items:flex-start; gap:10px } +.file-title { font-weight: 600; } +.file-actions { display:flex; gap:8px; align-items:center } +.file-details { background: #f9fafb; padding: 8px; border-radius: 6px; margin-top: 6px; font-size: 0.9em; border: 1px solid #e6e6e6 } +.file-sample { white-space: pre-wrap; background: #fff; border: 1px solid #e6e6e6; padding: 8px; margin-top: 6px; max-height: 200px; overflow: auto } +.parse-error { color: #7f1d1d; margin-top:6px } + +@media (max-width: 760px) { + .file-line { flex-direction: column; align-items: stretch; } + .file-actions { justify-content: flex-end; } +} diff --git a/src/app/join-backups/join-backups.component.html b/src/app/join-backups/join-backups.component.html new file mode 100644 index 0000000..3aa27d0 --- /dev/null +++ b/src/app/join-backups/join-backups.component.html @@ -0,0 +1,60 @@ +
+
+ +

Join Backups

+
+
+
Add multiple SMS Backup & Restore XML files, then merge into one.
+
+ + + + + +
+ +
+
Files: {{ preview.files }}
+
Messages (est): {{ preview.messages }}
+
Contacts (est): {{ preview.contacts }}
+
+ +
+

Added files

+
No files added yet.
+
    +
  • +
    + {{i+1}}. {{ f.name }} ({{ f.size | number }} bytes) + + + Reading... + Unreadable + + {{ f.readError }} + + +
    + + +
    +
    + +
    +
    Path: {{ f.path || '—' }}
    +
    Size: {{ f.size }} bytes
    +
    +
    Messages: {{ f.details.messages }}
    +
    Contacts: {{ f.details.contacts }}
    +
    {{ f.details.sample }}
    +
    Parse error: {{ f.details.parseError }}
    +
    +
    Parsing...
    +
    No content to show
    +
    +
  • +
+
+ +
{{ status }}
+
\ No newline at end of file diff --git a/src/app/join-backups/join-backups.component.ts b/src/app/join-backups/join-backups.component.ts new file mode 100644 index 0000000..0a48f64 --- /dev/null +++ b/src/app/join-backups/join-backups.component.ts @@ -0,0 +1,384 @@ +import { CommonModule } from '@angular/common'; +import { Component, NgZone } from '@angular/core'; +import { Router } from '@angular/router'; +import { CsvExportService } from '../csv-export.service'; +import { LogService } from '../log.service'; + +@Component({ + selector: 'app-join-backups', + standalone: true, + imports: [CommonModule], + templateUrl: './join-backups.component.html', + styleUrls: ['./join-backups.component.css'] +}) +export class JoinBackupsComponent { + selectedFiles: Array<{ name: string; size: number; text?: string; path?: string; fileRef?: File; readError?: string; reading?: boolean; expanded?: boolean; details?: { messages: number; contacts: number; sample?: string; parseError?: string } }> = []; + status = ''; + preview = { files: 0, messages: 0, contacts: 0 }; + + constructor( + private csvExport: CsvExportService, + private ngZone: NgZone, + private router: Router, + private logs: LogService + ) {} + + goBackToMain(): void { + void this.router.navigateByUrl('/main'); + } + + onBrowserFileInputChange(event: Event): void { + const input = event?.target as HTMLInputElement | null; + const files = input?.files ?? null; + void this.addFilesBrowser(files); + // allow selecting the same file(s) again + if (input) { + input.value = ''; + } + } + + async addFilesBrowser(files: FileList | null) { + if (!files) return; + const arr = Array.from(files); + this.logs.info('Join Backups: adding files (browser)', { count: arr.length }); + + const newEntries = arr.map((f) => ({ + name: f.name, + size: f.size, + text: undefined as string | undefined, + fileRef: f, + readError: undefined as string | undefined, + reading: true, + expanded: false, + details: undefined as any + })); + + this.ngZone.run(() => { + this.status = 'Reading files...'; + this.selectedFiles = [...(this.selectedFiles ?? []), ...newEntries]; + this.updatePreview(); + }); + + for (const entry of newEntries) { + await this.readBrowserEntry(entry); + } + + this.ngZone.run(() => { + this.updatePreview(); + this.status = ''; + }); + } + + private async readBrowserEntry(entry: any): Promise { + const f: File | undefined = entry?.fileRef; + if (!f) { + entry.readError = 'Missing browser file reference'; + entry.reading = false; + return; + } + + try { + let text: string; + if (typeof (f as any).text === 'function') { + text = await (f as any).text(); + } else { + text = await new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = () => resolve(String(reader.result ?? '')); + reader.onerror = () => reject(reader.error); + reader.readAsText(f); + }); + } + + this.ngZone.run(() => { + entry.text = text; + entry.size = text ? text.length : entry.size; + entry.readError = undefined; + }); + } catch (e) { + const readError = String((e as any)?.message ?? 'Read failed'); + this.logs.warn('Join Backups: failed to read file (browser)', { name: entry?.name, error: readError }); + this.ngZone.run(() => { + entry.readError = readError; + }); + } finally { + this.ngZone.run(() => { + entry.reading = false; + }); + } + } + + private detectTauriRuntime(): boolean { + try { + const protocol = (window?.location?.protocol ?? '').toLowerCase(); + if (protocol === 'tauri:' || protocol === 'asset:') return true; + const host = (window?.location?.hostname ?? '').toLowerCase(); + if (host === 'tauri.localhost' || host.endsWith('.tauri.localhost')) return true; + const w = window as any; + if (typeof w?.__TAURI__ !== 'undefined' || typeof w?.__TAURI_INTERNALS__ !== 'undefined') return true; + return (navigator?.userAgent ?? '').toLowerCase().includes('tauri'); + } catch { + return false; + } + } + + async addFilesNative() { + if (!this.detectTauriRuntime()) { + this.ngZone.run(() => { + this.status = 'Native file picker is only available in the desktop app (Tauri).'; + }); + this.logs.warn('Join Backups: native picker requested, but not in Tauri runtime'); + return; + } + + // Tauri open dialog + try { + const { open } = await import('@tauri-apps/plugin-dialog') as any; + const paths = await open({ multiple: true, filters: [{ name: 'XML', extensions: ['xml'] }] }); + if (!paths) return; + const pArr = Array.isArray(paths) ? paths : [paths]; + this.logs.info('Join Backups: adding files (native)', { count: pArr.length }); + const newEntries = pArr.map((p) => { + const name = String(p).split(/[\\/]/).pop(); + return { + name: name || String(p), + size: 0, + text: undefined as string | undefined, + path: String(p), + readError: undefined as string | undefined, + reading: true, + expanded: false, + details: undefined as any + }; + }); + + this.ngZone.run(() => { + this.status = 'Reading files...'; + this.selectedFiles = [...(this.selectedFiles ?? []), ...newEntries]; + this.updatePreview(); + }); + + const { readTextFile } = await import('@tauri-apps/plugin-fs') as any; + for (const entry of newEntries) { + try { + const text = await readTextFile(entry.path); + this.ngZone.run(() => { + entry.text = text; + entry.size = text ? text.length : 0; + entry.readError = undefined; + }); + } catch (e) { + const readError = String((e as any)?.message ?? 'Read failed'); + this.logs.warn('Join Backups: failed to read file (native)', { path: entry.path, error: readError }); + this.ngZone.run(() => { + entry.readError = readError; + }); + } finally { + this.ngZone.run(() => { + entry.reading = false; + }); + } + } + + this.ngZone.run(() => { + this.updatePreview(); + this.status = ''; + }); + } catch (e) { + console.warn('native pick error', e); + this.ngZone.run(() => { + this.status = `Native file picker not available: ${String((e as any)?.message ?? e)}`; + }); + this.logs.error('Join Backups: native file picker error', e); + } + } + + removeFile(index: number) { + this.ngZone.run(() => { + this.selectedFiles = (this.selectedFiles ?? []).filter((_, i) => i !== index); + this.updatePreview(); + }); + } + + async retryRead(index: number) { + const f = this.selectedFiles[index]; + if (!f) return; + f.readError = undefined; + f.reading = true; + try { + // Browser file reference + if (f.fileRef) { + await this.readBrowserEntry(f); + } else if (f.path) { + // Native path — ensure Tauri runtime available first + if (!this.detectTauriRuntime()) { + f.readError = 'Native runtime not available'; + return; + } + // Native path, use Tauri fs plugin + const { readTextFile } = await import('@tauri-apps/plugin-fs') as any; + const text = await readTextFile(f.path); + f.text = text; + f.size = text ? text.length : f.size; + } + this.updatePreview(); + } catch (e) { + f.readError = String((e as any)?.message ?? 'Read failed'); + } finally { + f.reading = false; + } + } + + toggleDetails(index: number) { + const f = this.selectedFiles[index]; + if (!f) return; + this.ngZone.run(() => { + f.expanded = !f.expanded; + if (f.expanded && !f.details && f.text) { + this.computeDetails(f); + } + }); + } + + private computeDetails(f: any) { + if (!f.text) { + f.details = undefined; + return; + } + try { + const parserCtor = (window as any)['fastXmlParser']?.XMLParser; + let messages = 0; + const contacts = new Set(); + if (parserCtor) { + const p = new parserCtor({ ignoreAttributes: false, attributeNamePrefix: '@_' }); + const parsed = p.parse(f.text); + const root = parsed && parsed[Object.keys(parsed)[0]]; + const sms = root && root.sms ? (Array.isArray(root.sms) ? root.sms : [root.sms]) : []; + messages = sms.length; + for (const m of sms) { + const addr = m['@_address'] || m.address || ''; + if (addr) contacts.add(addr); + } + } else { + const smsMatches = f.text.match(/ 500 ? f.text.slice(0, 500) + '...' : f.text; + f.details = { messages, contacts: contacts.size, sample }; + } catch (e) { + f.details = { messages: 0, contacts: 0, sample: '', parseError: String((e as any)?.message ?? 'Parse failed') }; + } + } + + updatePreview() { + const parser = (window as any)['fastXmlParser']?.XMLParser; + let messages = 0; + const contacts = new Set(); + for (const f of this.selectedFiles) { + if (!f.text) continue; + try { + const p = new parser({ ignoreAttributes: false, attributeNamePrefix: '@_' }); + const parsed = p.parse(f.text); + const root = parsed && parsed[Object.keys(parsed)[0]]; + const sms = root && root.sms ? (Array.isArray(root.sms) ? root.sms : [root.sms]) : []; + messages += sms.length; + for (const m of sms) { + const addr = m['@_address'] || m.address || ''; + if (addr) contacts.add(addr); + } + } catch (e) { + // ignore parse errors for preview + } + } + this.preview = { files: this.selectedFiles.length, messages, contacts: contacts.size }; + } + + async mergeAndSave() { + if (!this.selectedFiles.length) { + this.status = 'No files selected'; + return; + } + this.status = 'Merging...'; + try { + this.logs.info('Join Backups: merge started', { files: this.selectedFiles.length }); + const parser = (window as any)['fastXmlParser'].XMLParser; + const builder = (window as any)['fastXmlParser'].XMLBuilder; + const p = new parser({ ignoreAttributes: false, attributeNamePrefix: '@_' }); + const b = new builder({ ignoreAttributes: false, attributeNamePrefix: '@_', format: true }); + + let merged = []; + let topName: string | null = null; + let topAttrs: any = {}; + + for (const f of this.selectedFiles) { + if (!f.text) continue; + const parsed = p.parse(f.text); + const keys = Object.keys(parsed); + if (!keys.length) continue; + const rootName = keys[0]; + const root = parsed[rootName]; + if (!topName) { + topName = rootName; + for (const k of Object.keys(root || {})) if (k.startsWith('@_')) topAttrs[k] = root[k]; + } + const sms = root && root.sms ? (Array.isArray(root.sms) ? root.sms : [root.sms]) : []; + merged = merged.concat(sms); + } + + const outRoot: any = Object.assign({}, topAttrs); + outRoot['sms'] = merged; + outRoot['@_count'] = String(merged.length); + const outObj: any = {}; + outObj[topName || 'smses'] = outRoot; + const xml = b.build(outObj); + + // Save using Tauri dialog + fs if available, else fallback to download + try { + const { save } = await import('@tauri-apps/plugin-dialog') as any; + const path = await save({ defaultPath: 'merged.xml' }); + if (path) { + const { writeTextFile } = await import('@tauri-apps/plugin-fs') as any; + await writeTextFile(path, xml); + // show toast + try { const { ToastService } = await import('../toast.service'); } catch (e) {} + this.status = `Saved to ${path}`; + this.logs.info('Join Backups: merge saved (native)', { path, messages: merged.length }); + return; + } + } catch (e) { + console.warn('native save failed', e); + this.logs.warn('Join Backups: native save failed, falling back to browser download', e); + } + + // browser fallback + const blob = new Blob([xml], { type: 'application/xml' }); + const url = URL.createObjectURL(blob); + const link = document.createElement('a'); + link.href = url; + link.download = 'merged.xml'; + document.body.appendChild(link); + link.click(); + link.remove(); + URL.revokeObjectURL(url); + this.status = 'Downloaded merged.xml'; + this.logs.info('Join Backups: merge downloaded (browser)', { messages: merged.length }); + } catch (e) { + console.error(e); + this.status = 'Merge failed: ' + String((e as any)?.message || e); + this.logs.error('Join Backups: merge failed', e); + } + } + + clearAll() { + this.ngZone.run(() => { + this.selectedFiles = []; + this.updatePreview(); + this.status = ''; + }); + } +} diff --git a/src/app/loader-status.ts b/src/app/loader-status.ts new file mode 100644 index 0000000..bb575bd --- /dev/null +++ b/src/app/loader-status.ts @@ -0,0 +1,13 @@ +export type LoadStatus = 'idle' | 'busy' | 'ok' | 'error'; + +export interface LoaderStatusUpdate { + source: 'sms' | 'vcf'; + status: LoadStatus; + text: string; + updatedAt: number; + // SMS-only (optional) + progressPercent?: number; + bytesRead?: number; + totalBytes?: number; + parsedCount?: number; +} diff --git a/src/app/log.service.ts b/src/app/log.service.ts new file mode 100644 index 0000000..83a9a55 --- /dev/null +++ b/src/app/log.service.ts @@ -0,0 +1,84 @@ +import { Injectable, NgZone } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; + +export type LogLevel = 'debug' | 'info' | 'warn' | 'error'; + +export type LogEntry = { + id: number; + at: number; + level: LogLevel; + message: string; + details?: unknown; +}; + +@Injectable({ + providedIn: 'root' +}) +export class LogService { + private readonly maxEntries = 500; + private nextId = 1; + private readonly _entries = new BehaviorSubject([]); + readonly entries$ = this._entries.asObservable(); + + constructor(private ngZone: NgZone) {} + + clear(): void { + this.ngZone.run(() => { + this._entries.next([]); + }); + } + + debug(message: string, details?: unknown): void { + this.add('debug', message, details); + } + + info(message: string, details?: unknown): void { + this.add('info', message, details); + } + + warn(message: string, details?: unknown): void { + this.add('warn', message, details); + } + + error(message: string, details?: unknown): void { + this.add('error', message, details); + } + + add(level: LogLevel, message: string, details?: unknown): void { + const entry: LogEntry = { + id: this.nextId++, + at: Date.now(), + level, + message: String(message ?? ''), + details + }; + + this.ngZone.run(() => { + const current = this._entries.value; + const next = [...current, entry]; + if (next.length > this.maxEntries) { + next.splice(0, next.length - this.maxEntries); + } + this._entries.next(next); + }); + } + + toText(entries?: LogEntry[]): string { + const list = entries ?? this._entries.value; + return list + .map((e) => { + const ts = new Date(e.at).toISOString(); + const details = typeof e.details === 'undefined' ? '' : `\n details: ${safeJson(e.details)}`; + return `[${ts}] ${e.level.toUpperCase()} ${e.message}${details}`; + }) + .join('\n'); + } +} + +function safeJson(value: unknown): string { + try { + return JSON.stringify(value); + } catch { + return String(value); + } +} diff --git a/src/app/log/log.component.css b/src/app/log/log.component.css new file mode 100644 index 0000000..d116cd4 --- /dev/null +++ b/src/app/log/log.component.css @@ -0,0 +1,214 @@ +:host { + display: block; + height: 100%; + min-height: 0; +} + +.log-page { + max-width: 1100px; + margin: 0 auto; + padding: 14px 16px; + display: flex; + flex-direction: column; + gap: 12px; + height: 100%; + min-height: 0; +} + +.log-header { + display: flex; + align-items: flex-start; + justify-content: space-between; + gap: 12px; +} + +.log-title h2 { + margin: 0; + font-size: 20px; + line-height: 1.2; + font-weight: 600; +} + +.log-subtitle { + margin-top: 4px; + color: rgba(0, 0, 0, 0.6); + font-size: 13px; +} + +.log-actions { + display: flex; + gap: 8px; + flex-wrap: wrap; + justify-content: flex-end; +} + +.log-filters { + display: flex; + align-items: flex-end; + gap: 10px; + flex-wrap: wrap; + padding: 12px; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 10px; + background: #fff; +} + +.filter { + display: flex; + flex-direction: column; + gap: 6px; + min-width: 160px; +} + +.filter--grow { + flex: 1; + min-width: 220px; +} + +.filter span { + font-size: 12px; + color: rgba(0, 0, 0, 0.65); +} + +select, +input[type='text'] { + border: 1px solid rgba(0, 0, 0, 0.22); + border-radius: 8px; + padding: 8px 10px; + font-size: 14px; + background: #fff; +} + +.count { + margin-left: auto; + color: rgba(0, 0, 0, 0.6); + font-size: 12px; + white-space: nowrap; +} + +.log-list { + flex: 1; + min-height: 0; + overflow: auto; + border: 1px solid rgba(0, 0, 0, 0.12); + border-radius: 10px; + background: #fff; +} + +.log-row { + display: grid; + grid-template-columns: 180px 70px 1fr; + gap: 10px; + padding: 10px 12px; + border-bottom: 1px solid rgba(0, 0, 0, 0.08); +} + +.log-row:last-child { + border-bottom: none; +} + +.when { + color: rgba(0, 0, 0, 0.65); + font-size: 12px; +} + +.level { + font-weight: 700; + font-size: 12px; + text-transform: uppercase; + letter-spacing: 0.04em; +} + +.level--debug { + color: #546e7a; +} + +.level--info { + color: #1565c0; +} + +.level--warn { + color: #ef6c00; +} + +.level--error { + color: #c62828; +} + +.msg { + font-size: 13px; + white-space: pre-wrap; + word-break: break-word; +} + +.details { + grid-column: 1 / -1; + margin: 0; + padding: 10px; + border-radius: 8px; + background: rgba(0, 0, 0, 0.04); + overflow: auto; + max-height: 280px; +} + +.log-empty { + padding: 24px; + border: 1px dashed rgba(0, 0, 0, 0.2); + border-radius: 10px; + background: rgba(255, 255, 255, 0.6); +} + +.log-empty__title { + font-weight: 600; + margin-bottom: 6px; +} + +.log-empty__hint { + color: rgba(0, 0, 0, 0.65); +} + +/* Reuse Join Backups button style so it looks consistent */ +.jb-btn { + display: inline-flex; + align-items: center; + justify-content: center; + gap: 6px; + padding: 8px 12px; + border-radius: 10px; + border: 1px solid rgba(0, 0, 0, 0.18); + background: #fff; + color: #111; + font-weight: 600; + cursor: pointer; +} + +.jb-btn:hover { + background: rgba(0, 0, 0, 0.03); +} + +.jb-btn:active { + transform: translateY(1px); +} + +.jb-btn--danger { + border-color: rgba(198, 40, 40, 0.35); + color: #c62828; +} + +@media (max-width: 740px) { + .log-row { + grid-template-columns: 1fr; + } + + .when { + order: 1; + } + + .level { + order: 2; + } + + .msg { + order: 3; + } +} diff --git a/src/app/log/log.component.html b/src/app/log/log.component.html new file mode 100644 index 0000000..a66ce47 --- /dev/null +++ b/src/app/log/log.component.html @@ -0,0 +1,54 @@ +
+
+
+

Log

+
Recent app events, warnings, and errors
+
+ +
+ + + +
+
+ +
+ + + +
{{ filtered.length }} / {{ entries.length }}
+
+ +
+
+
{{ formatTime(e.at) }}
+
{{ e.level }}
+
{{ e.message }}
+
{{ d | json }}
+
+
+ + +
+
No log entries yet
+
Try importing a backup or joining backups; errors and progress will appear here.
+
+
+
diff --git a/src/app/log/log.component.ts b/src/app/log/log.component.ts new file mode 100644 index 0000000..40b8612 --- /dev/null +++ b/src/app/log/log.component.ts @@ -0,0 +1,82 @@ +import { CommonModule } from '@angular/common'; +import { Component, OnDestroy, OnInit } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { Router } from '@angular/router'; +import { Subscription } from 'rxjs'; + +import { LogEntry, LogLevel, LogService } from '../log.service'; + +@Component({ + selector: 'app-log', + standalone: true, + imports: [CommonModule, FormsModule], + templateUrl: './log.component.html', + styleUrls: ['./log.component.css'] +}) +export class LogComponent implements OnInit, OnDestroy { + entries: LogEntry[] = []; + filtered: LogEntry[] = []; + query = ''; + level: LogLevel | 'all' = 'all'; + + private sub?: Subscription; + + constructor(private logs: LogService, private router: Router) {} + + ngOnInit(): void { + this.sub = this.logs.entries$.subscribe((entries) => { + this.entries = entries; + this.applyFilter(); + }); + } + + ngOnDestroy(): void { + this.sub?.unsubscribe(); + } + + goMain(): void { + void this.router.navigateByUrl('/main'); + } + + clear(): void { + this.logs.clear(); + } + + applyFilter(): void { + const q = (this.query || '').trim().toLowerCase(); + const lvl = this.level; + + this.filtered = (this.entries ?? []).filter((e) => { + if (lvl !== 'all' && e.level !== lvl) return false; + if (!q) return true; + const hay = `${e.level} ${e.message} ${safeString(e.details)}`.toLowerCase(); + return hay.includes(q); + }); + } + + formatTime(ms: number): string { + const d = new Date(ms); + try { + return new Intl.DateTimeFormat(undefined, { dateStyle: 'short', timeStyle: 'medium' }).format(d); + } catch { + return d.toLocaleString(); + } + } + + async copy(): Promise { + try { + await navigator.clipboard.writeText(this.logs.toText(this.filtered)); + } catch { + // ignore + } + } +} + +function safeString(value: unknown): string { + if (typeof value === 'string') return value; + try { + return JSON.stringify(value); + } catch { + return String(value ?? ''); + } +} diff --git a/src/app/main/main.component.css b/src/app/main/main.component.css index e69de29..1486147 100644 --- a/src/app/main/main.component.css +++ b/src/app/main/main.component.css @@ -0,0 +1,44 @@ +.empty-state { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + padding: 40px; + text-align: center; + color: #757575; +} + +.empty-state-icon { + font-size: 72px; + color: #bdbdbd; + margin-bottom: 16px; +} + +.empty-state h3 { + margin: 16px 0 8px 0; + color: #424242; + font-weight: 400; +} + +.empty-state p { + max-width: 400px; + line-height: 1.6; + margin-bottom: 24px; +} + +.empty-state-note { + display: flex; + align-items: center; + gap: 8px; + padding: 12px 16px; + background: #e3f2fd; + border-radius: 4px; + color: #1976d2; + font-size: 14px; + max-width: 500px; +} + +.empty-state-note .material-icons { + font-size: 20px; +} diff --git a/src/app/main/main.component.html b/src/app/main/main.component.html index b2fe5f3..0fee8c7 100644 --- a/src/app/main/main.component.html +++ b/src/app/main/main.component.html @@ -4,7 +4,15 @@
-

{{messagesPlaceholder}}

{{countryCodePlaceholder}}

+
+ chat_bubble_outline +

No Messages Loaded

+

{{messagesPlaceholder}}

+
+ info_outline + {{countryCodePlaceholder}} +
+
\ No newline at end of file diff --git a/src/app/main/main.component.spec.ts b/src/app/main/main.component.spec.ts index 989c365..397799c 100644 --- a/src/app/main/main.component.spec.ts +++ b/src/app/main/main.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; import { MainComponent } from './main.component'; +import { SmsLoaderService } from '../sms-loader.service'; +import { SmsStoreService } from '../sms-store.service'; describe('MainComponent', () => { let component: MainComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ MainComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CommonModule], + declarations: [ MainComponent ], + providers: [SmsStoreService, SmsLoaderService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(MainComponent); diff --git a/src/app/main/main.component.ts b/src/app/main/main.component.ts index bfc528e..3c357fa 100644 --- a/src/app/main/main.component.ts +++ b/src/app/main/main.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from '@angular/core'; -import {Subscription} from 'rxjs/Subscription'; +import { Subscription } from 'rxjs'; import { SmsLoaderComponent } from '../sms-loader/sms-loader.component'; import { MessageListComponent } from '../message-list/message-list.component'; @@ -9,7 +9,8 @@ import { SmsLoaderService } from '../sms-loader.service'; @Component({ selector: 'app-main', templateUrl: './main.component.html', - styleUrls: ['./main.component.css'] + styleUrls: ['./main.component.css'], + standalone: false }) export class MainComponent implements OnInit { @@ -23,7 +24,7 @@ export class MainComponent implements OnInit { } ngOnInit() { - this.messagesPlaceholder = 'Messages will appear here. Please select a backup file. Large backups will freeze the UI.'; + this.messagesPlaceholder = 'Messages will appear here. Please select a backup file. Large backups may take a moment to load.'; this.countryCodePlaceholder = 'Note: Please check SETTINGS to change your country code before loading!'; this.contactsPlaceholder = 'Contacts will appear here. Please select a backup file.'; this.loadingSubscription = this.smsStoreService.messagesLoaded$ diff --git a/src/app/message-list/export-options-dialog.component.css b/src/app/message-list/export-options-dialog.component.css new file mode 100644 index 0000000..ee445a1 --- /dev/null +++ b/src/app/message-list/export-options-dialog.component.css @@ -0,0 +1,86 @@ +.export-dialog-overlay { + position: fixed; + top: 0; + left: 0; + right: 0; + bottom: 0; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; +} + +.export-dialog-container { + background: white; + border-radius: 2px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2); + max-width: 500px; + width: 90%; + max-height: 80vh; + overflow-y: auto; +} + +.export-dialog-header { + padding: 24px 24px 0; + border-bottom: 1px solid #e0e0e0; +} + +.export-dialog-header h4 { + margin: 0 0 16px 0; + font-size: 20px; + font-weight: 500; +} + +.export-dialog-content { + padding: 24px; +} + +.export-section { + margin-bottom: 24px; +} + +.export-section h5 { + margin: 0 0 12px 0; + font-size: 16px; + font-weight: 500; + color: #424242; +} + +.export-hint { + margin: 8px 0 0 0; + padding-left: 28px; + font-size: 12px; + line-height: 1.4; + color: #616161; +} + +.mdl-radio { + display: block; + margin-bottom: 8px; +} + +.field-selection-actions { + margin-bottom: 16px; +} + +.field-selection-actions button { + margin-right: 8px; +} + +.field-checkboxes { + display: flex; + flex-direction: column; +} + +.mdl-checkbox { + display: block; + margin-bottom: 8px; +} + +.export-dialog-actions { + padding: 8px 24px 24px; + display: flex; + justify-content: flex-end; + gap: 8px; +} diff --git a/src/app/message-list/export-options-dialog.component.html b/src/app/message-list/export-options-dialog.component.html new file mode 100644 index 0000000..7d67167 --- /dev/null +++ b/src/app/message-list/export-options-dialog.component.html @@ -0,0 +1,112 @@ +
+
+
+

Export Options

+
+ +
+ +
+
Export Scope
+ + +
+ + +
+
Media
+ +
+ The ZIP will include messages.csv plus files under media/.... Any inline data: images in Body (HTML) are rewritten to point at those files. +
+
+ + +
+
Fields to Export
+
+ + +
+ +
+ + + + + + + + + + + + + + + +
+
+
+ +
+ + +
+
+
diff --git a/src/app/message-list/export-options-dialog.component.spec.ts b/src/app/message-list/export-options-dialog.component.spec.ts new file mode 100644 index 0000000..5ff6a49 --- /dev/null +++ b/src/app/message-list/export-options-dialog.component.spec.ts @@ -0,0 +1,98 @@ +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; +import { FormsModule } from '@angular/forms'; + +import { ExportOptionsDialogComponent, ExportOptions } from './export-options-dialog.component'; + +describe('ExportOptionsDialogComponent', () => { + let component: ExportOptionsDialogComponent; + let fixture: ComponentFixture; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CommonModule, FormsModule], + declarations: [ExportOptionsDialogComponent], + schemas: [CUSTOM_ELEMENTS_SCHEMA], + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ExportOptionsDialogComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + it('should default to conversation scope', () => { + expect(component.scope).toBe('conversation'); + }); + + it('should have all fields selected by default', () => { + expect(component.fields.conversationId).toBe(true); + expect(component.fields.contactName).toBe(true); + expect(component.fields.direction).toBe(true); + expect(component.fields.type).toBe(true); + expect(component.fields.timestampMs).toBe(true); + expect(component.fields.dateIso).toBe(true); + expect(component.fields.bodyText).toBe(true); + expect(component.fields.bodyHtml).toBe(true); + }); + + it('should default to not exporting MMS media as files', () => { + expect(component.mmsMediaAsFiles).toBe(false); + }); + + it('should select all fields when selectAllFields is called', () => { + component.fields.bodyText = false; + component.fields.bodyHtml = false; + component.selectAllFields(); + expect(component.fields.bodyText).toBe(true); + expect(component.fields.bodyHtml).toBe(true); + }); + + it('should deselect all fields when deselectAllFields is called', () => { + component.deselectAllFields(); + expect(component.fields.conversationId).toBe(false); + expect(component.fields.contactName).toBe(false); + expect(component.fields.direction).toBe(false); + expect(component.fields.type).toBe(false); + expect(component.fields.timestampMs).toBe(false); + expect(component.fields.dateIso).toBe(false); + expect(component.fields.bodyText).toBe(false); + expect(component.fields.bodyHtml).toBe(false); + }); + + it('should emit onCancel when cancel is called', () => { + let emitted = false; + component.onCancel.subscribe(() => { + emitted = true; + }); + component.cancel(); + expect(emitted).toBe(true); + }); + + it('should emit onExport with correct options when export is called', () => { + component.scope = 'all'; + component.fields.bodyHtml = false; + component.mmsMediaAsFiles = true; + + let exportedOptions: ExportOptions | null = null; + component.onExport.subscribe((options) => { + exportedOptions = options; + }); + + component.export(); + + expect(exportedOptions).not.toBeNull(); + expect(exportedOptions!.scope).toBe('all'); + // When media-as-files is enabled, bodyHtml is forced on. + expect(exportedOptions!.mmsMediaAsFiles).toBe(true); + expect(exportedOptions!.fields.bodyHtml).toBe(true); + expect(exportedOptions!.fields.bodyText).toBe(true); + }); +}); diff --git a/src/app/message-list/export-options-dialog.component.ts b/src/app/message-list/export-options-dialog.component.ts new file mode 100644 index 0000000..fa34067 --- /dev/null +++ b/src/app/message-list/export-options-dialog.component.ts @@ -0,0 +1,76 @@ +import { Component, EventEmitter, Input, Output } from '@angular/core'; + +export interface ExportOptions { + scope: 'conversation' | 'all'; + // When enabled, export creates a .zip with CSV + extracted media files. + mmsMediaAsFiles: boolean; + fields: { + conversationId: boolean; + contactName: boolean; + direction: boolean; + type: boolean; + timestampMs: boolean; + dateIso: boolean; + bodyText: boolean; + bodyHtml: boolean; + }; +} + +@Component({ + selector: 'export-options-dialog', + templateUrl: './export-options-dialog.component.html', + styleUrls: ['./export-options-dialog.component.css'], + standalone: false +}) +export class ExportOptionsDialogComponent { + @Input() isOpen = false; + @Output() onCancel = new EventEmitter(); + @Output() onExport = new EventEmitter(); + + // Export scope + scope: 'conversation' | 'all' = 'conversation'; + + // Media export + mmsMediaAsFiles = false; + + // Field selections - all enabled by default + fields = { + conversationId: true, + contactName: true, + direction: true, + type: true, + timestampMs: true, + dateIso: true, + bodyText: true, + bodyHtml: true + }; + + cancel(): void { + this.onCancel.emit(); + } + + export(): void { + if (this.mmsMediaAsFiles) { + // To make the exported media usable, we need HTML with file references. + this.fields.bodyHtml = true; + } + + this.onExport.emit({ + scope: this.scope, + mmsMediaAsFiles: this.mmsMediaAsFiles, + fields: { ...this.fields } + }); + } + + selectAllFields(): void { + Object.keys(this.fields).forEach(key => { + this.fields[key as keyof typeof this.fields] = true; + }); + } + + deselectAllFields(): void { + Object.keys(this.fields).forEach(key => { + this.fields[key as keyof typeof this.fields] = false; + }); + } +} diff --git a/src/app/message-list/message-list.component.css b/src/app/message-list/message-list.component.css index e69de29..eeb6d1f 100644 --- a/src/app/message-list/message-list.component.css +++ b/src/app/message-list/message-list.component.css @@ -0,0 +1,58 @@ +:host { + display: block; + height: 100%; + min-height: 0; +} + +.message-container { + display: flex; + flex-direction: column; + height: 100%; + min-height: 0; + padding: 16px 0; + gap: 8px; +} + +.message-body { + word-wrap: break-word; + line-height: 1.4; +} + +.message-meta { + font-size: 11px; + color: #757575; + margin-top: 4px; + display: flex; + gap: 8px; +} + +.message-type { + font-weight: 500; +} + +.message-date { + opacity: 0.8; +} + +/* Virtual scroll viewport and row styles */ +.message-viewport { + flex: 1 1 auto; + min-height: 0; + height: auto; + display: block; + overflow: auto; + box-sizing: border-box; + padding: 8px 0 24px; +} + +.message-row { + margin-bottom: 6px; + padding: 8px 12px; + border-radius: 10px; + max-width: 76%; + box-shadow: var(--shadow-sm); + border: 1px solid rgba(0,0,0,0.06); + display: flex; + flex-direction: column; +} + diff --git a/src/app/message-list/message-list.component.html b/src/app/message-list/message-list.component.html index b9ff43a..f6a205b 100644 --- a/src/app/message-list/message-list.component.html +++ b/src/app/message-list/message-list.component.html @@ -1,13 +1,34 @@ -
-
    -
  • - - - {{message.type | messageType}}: {{message.date}} - -
  • -
+
+
+
+ +
+ +
+ + + + +
+
+
+ {{message.type | messageType}} + {{message.date}} +
+
+
\ No newline at end of file diff --git a/src/app/message-list/message-list.component.spec.ts b/src/app/message-list/message-list.component.spec.ts index b33a153..963d50f 100644 --- a/src/app/message-list/message-list.component.spec.ts +++ b/src/app/message-list/message-list.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { CommonModule } from '@angular/common'; import { MessageListComponent } from './message-list.component'; +import { MessageTypePipe } from '../message-type.pipe'; +import { SmsStoreService } from '../sms-store.service'; describe('MessageListComponent', () => { let component: MessageListComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ MessageListComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [CommonModule], + declarations: [ MessageListComponent, MessageTypePipe ], + providers: [SmsStoreService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(MessageListComponent); diff --git a/src/app/message-list/message-list.component.ts b/src/app/message-list/message-list.component.ts index 72f13be..0516d1b 100644 --- a/src/app/message-list/message-list.component.ts +++ b/src/app/message-list/message-list.component.ts @@ -1,17 +1,21 @@ -import { Component, OnInit } from '@angular/core'; -import {Subscription} from 'rxjs/Subscription'; +import { AfterViewInit, Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core'; +import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling'; +import { Subscription } from 'rxjs'; import { Message } from '../message'; import { Contact } from '../contact'; import { SmsStoreService } from '../sms-store.service'; +import { CsvExportService } from '../csv-export.service'; +import { ExportOptions } from './export-options-dialog.component'; @Component({ selector: 'message-list', templateUrl: './message-list.component.html', - styleUrls: ['./message-list.component.css'] + styleUrls: ['./message-list.component.css'], + standalone: false }) -export class MessageListComponent implements OnInit { +export class MessageListComponent implements OnInit, AfterViewInit { messages: Message[]; messageMap: Map; @@ -20,8 +24,30 @@ export class MessageListComponent implements OnInit { loadingSubscription: Subscription; contactClickedSubscription: Subscription; selectedContact: Contact; + + showExportDialog = false; + loadingOlder = false; + hasMoreMessages = false; + private oldestLoadedDateMs: number | null = null; + private readonly pageSize = 200; + private readonly autoLoadThresholdPx = 220; + private readonly autoLoadMinIntervalMs = 750; + private lastAutoLoadAtMs = 0; + private scrollRafPending = false; + private scrollContainerEl: HTMLElement | null = null; + private detachScrollListener: (() => void) | null = null; - constructor(private smsStoreService: SmsStoreService) { } + // Adaptive virtual scroll item size (measured at runtime) + viewportItemSize = 120; + + @ViewChild(CdkVirtualScrollViewport, { static: false }) private viewport?: CdkVirtualScrollViewport; + + constructor( + private smsStoreService: SmsStoreService, + private csvExportService: CsvExportService, + private elementRef: ElementRef, + private ngZone: NgZone + ) { } ngOnInit() { this.loadingSubscription = this.smsStoreService.messagesLoaded$ @@ -35,26 +61,369 @@ export class MessageListComponent implements OnInit { .subscribe(contact => { this.selectedContact = contact; if (contact) { - this.messages = this.messageMap.get(contact.address); + this.loadLatestForSelectedContact(); } return; }); } + ngAfterViewInit(): void { + this.initScrollContainer(); + } + + private initScrollContainer(): void { + // Target the virtual scroll viewport if present, otherwise fall back to the messages container + const host = this.elementRef?.nativeElement as HTMLElement | null; + this.scrollContainerEl = host?.querySelector('.message-viewport') as HTMLElement | null || host?.closest('.messages') as HTMLElement | null; + if (!this.scrollContainerEl) { + return; + } + + this.ngZone.runOutsideAngular(() => { + const handler = () => { + if (this.scrollRafPending) { + return; + } + this.scrollRafPending = true; + requestAnimationFrame(() => { + this.scrollRafPending = false; + this.ngZone.run(() => this.maybeAutoLoadOlder()); + }); + }; + + this.scrollContainerEl!.addEventListener('scroll', handler, { passive: true }); + this.detachScrollListener = () => this.scrollContainerEl?.removeEventListener('scroll', handler as any); + }); + } + + private maybeAutoLoadOlder(): void { + const el = this.scrollContainerEl; + if (!el || !this.hasMoreMessages || this.loadingOlder) { + return; + } + if (el.scrollTop > this.autoLoadThresholdPx) { + return; + } + const now = Date.now(); + if (now - this.lastAutoLoadAtMs < this.autoLoadMinIntervalMs) { + return; + } + this.lastAutoLoadAtMs = now; + void this.loadOlderMessages(); + } + + private async loadLatestForSelectedContact(): Promise { + this.messages = []; + this.oldestLoadedDateMs = null; + this.hasMoreMessages = false; + this.loadingOlder = false; + + const contact = this.selectedContact; + if (!contact?.address) { + return; + } + + // Fetch the latest messages (page-limited). + const dbStart = performance.now(); + const msgs = await this.smsStoreService.getLatestMessages(contact.address, this.pageSize); + const dbMs = performance.now() - dbStart; + console.debug('[perf] getLatestMessages db time (ms):', dbMs); + + if (!msgs?.length) { + this.messages = []; + this.oldestLoadedDateMs = null; + this.hasMoreMessages = false; + return; + } + + // Quick-first render: show the newest N messages immediately to improve perceived load time, + // then fill in the rest asynchronously so the UI isn't blocked rendering a large batch at once. + const IMMEDIATE_COUNT = Math.min(50, msgs.length); + const newestSlice = msgs.slice(-IMMEDIATE_COUNT); + + const renderStart = performance.now(); + const total = Number(contact.messageCount ?? 0); + + // Dexie promises can resolve outside Angular zone; wrap assignment to trigger change detection. + this.ngZone.run(() => { + this.messages = newestSlice; + this.oldestLoadedDateMs = newestSlice?.length ? (newestSlice[0].date?.getTime?.() ?? Number(newestSlice[0].timestamp) ?? null) : null; + this.hasMoreMessages = total > (newestSlice?.length ?? 0); + }); + + // Measure first rendered row height and update viewport item size so CDK uses realistic sizing + requestAnimationFrame(() => { + const firstRow = this.elementRef.nativeElement.querySelector('.message-row') as HTMLElement | null; + if (firstRow) { + const measured = Math.max(48, Math.round(firstRow.offsetHeight)); + if (measured !== this.viewportItemSize) { + this.viewportItemSize = measured; + if (this.viewport) { + // Tell CDK to recalc + this.viewport.checkViewportSize(); + } + console.debug('[perf] measured firstRow height -> itemSize:', measured); + } + } + + const renderMs = performance.now() - renderStart; + console.debug('[perf] initial render (ms):', renderMs); + + // Scroll to bottom to show latest content early. + const el = this.scrollContainerEl; + if (el) { + requestAnimationFrame(() => { + el.scrollTop = el.scrollHeight; + }); + } + }); + + // Fill remaining messages in a microtask so the browser can paint first. + if (msgs.length > IMMEDIATE_COUNT) { + setTimeout(() => { + const renderAllStart = performance.now(); + this.ngZone.run(() => { + this.messages = msgs; + this.oldestLoadedDateMs = msgs?.length ? (msgs[0].date?.getTime?.() ?? Number(msgs[0].timestamp) ?? null) : null; + this.hasMoreMessages = total > (msgs?.length ?? 0); + }); + + // Re-measure and re-scroll after full set renders. + const el = this.scrollContainerEl; + requestAnimationFrame(() => { + const firstRow = this.elementRef.nativeElement.querySelector('.message-row') as HTMLElement | null; + if (firstRow) { + const measured = Math.max(48, Math.round(firstRow.offsetHeight)); + if (measured !== this.viewportItemSize) { + this.viewportItemSize = measured; + if (this.viewport) { + this.viewport.checkViewportSize(); + } + console.debug('[perf] re-measured firstRow height -> itemSize:', measured); + } + } + + if (el) { + el.scrollTop = el.scrollHeight; + } + console.debug('[perf] full render (ms):', performance.now() - renderAllStart); + }); + }, 80); + } + } + + async loadOlderMessages(): Promise { + if (this.loadingOlder) { + return; + } + const contact = this.selectedContact; + if (!contact?.address || this.oldestLoadedDateMs === null) { + return; + } + const el = this.scrollContainerEl; + const prevScrollHeight = el ? el.scrollHeight : 0; + const prevScrollTop = el ? el.scrollTop : 0; + + this.loadingOlder = true; + try { + const older = await this.smsStoreService.getOlderMessages(contact.address, this.oldestLoadedDateMs, this.pageSize); + if (!older?.length) { + this.ngZone.run(() => { + this.hasMoreMessages = false; + }); + return; + } + this.ngZone.run(() => { + this.messages = [...older, ...(this.messages ?? [])]; + this.oldestLoadedDateMs = older[0].date?.getTime?.() ?? Number(older[0].timestamp) ?? this.oldestLoadedDateMs; + const total = Number(contact.messageCount ?? 0); + this.hasMoreMessages = total > (this.messages?.length ?? 0); + }); + + // Preserve viewport position when prepending. + if (el) { + requestAnimationFrame(() => { + const newScrollHeight = el.scrollHeight; + const delta = newScrollHeight - prevScrollHeight; + el.scrollTop = prevScrollTop + delta; + }); + } + } finally { + this.loadingOlder = false; + } + } + ngOnDestroy() { this.loadingSubscription.unsubscribe(); this.contactClickedSubscription.unsubscribe(); + this.detachScrollListener?.(); } getAllMessages(): void { this.messages = new Array(); - this.smsStoreService.getAllMessages().then(messageMap => { - this.messageMap = messageMap; - }); + this.smsStoreService.getAllMessages().then(messageMap => { + this.ngZone.run(() => { + this.messageMap = messageMap; + }); + }); } showMessages(contactId: string): void { - this.messages = this.messageMap.get(contactId); + this.smsStoreService.getLatestMessages(contactId, this.pageSize).then((msgs) => { + this.ngZone.run(() => { + this.messages = msgs; + this.oldestLoadedDateMs = msgs?.length ? (msgs[0].date?.getTime?.() ?? Number(msgs[0].timestamp) ?? null) : null; + }); + const el = this.scrollContainerEl; + if (el) { + requestAnimationFrame(() => { + el.scrollTop = el.scrollHeight; + }); + } + }); + } + + openExportDialog(): void { + this.showExportDialog = true; + } + + closeExportDialog(): void { + this.showExportDialog = false; + } + + handleExport(options: ExportOptions): void { + this.showExportDialog = false; + + if (options.scope === 'conversation') { + this.exportConversation(options); + } else { + this.exportAllMessages(options); + } + } + + private exportConversation(options: ExportOptions): void { + if (!this.selectedContact) { + return; + } + + const conversationId = this.selectedContact.address; + const columns = this.getSelectedColumns(options.fields); + const namePart = this.selectedContact.name || this.selectedContact.address || 'conversation'; + + const run = async () => { + const messages = await this.smsStoreService.getMessages(conversationId); + if (!messages?.length) { + return; + } + + if (options.mmsMediaAsFiles) { + const mediaFiles: Array<{ path: string; content: Uint8Array }> = []; + const rows = messages.map((m, messageIndex) => { + const extracted = this.csvExportService.extractInlineBase64MediaFromHtml(m.body, { + conversationId, + messageIndex, + timestampMs: Number(m.timestamp) + }); + extracted.files.forEach((f) => mediaFiles.push({ path: f.path, content: f.bytes })); + return this.messageToRow(m, conversationId, extracted.html); + }); + + const csv = this.csvExportService.buildCsv(rows, columns); + this.csvExportService.downloadZip(`sms-conversation-${namePart}`, [ + { path: 'messages.csv', content: csv }, + ...mediaFiles + ]); + return; + } + + const rows = messages.map((m) => this.messageToRow(m, conversationId)); + this.csvExportService.downloadCsv(`sms-conversation-${namePart}`, rows, columns); + }; + + void run(); + } + + private exportAllMessages(options: ExportOptions): void { + const columns = this.getSelectedColumns(options.fields); + + const run = async () => { + const contacts = await this.smsStoreService.getAllContacts(); + if (!contacts?.length) { + return; + } + + if (options.mmsMediaAsFiles) { + const mediaFiles: Array<{ path: string; content: Uint8Array }> = []; + const rows: Array> = []; + for (const c of contacts) { + const conversationId = c.address; + const messages = await this.smsStoreService.getMessages(conversationId); + messages.forEach((m, messageIndex) => { + const extracted = this.csvExportService.extractInlineBase64MediaFromHtml(m.body, { + conversationId, + messageIndex, + timestampMs: Number(m.timestamp) + }); + extracted.files.forEach((f) => mediaFiles.push({ path: f.path, content: f.bytes })); + rows.push(this.messageToRow(m, conversationId, extracted.html)); + }); + } + const csv = this.csvExportService.buildCsv(rows, columns); + this.csvExportService.downloadZip('sms-all-messages', [ + { path: 'messages.csv', content: csv }, + ...mediaFiles + ]); + return; + } + + const rows: Array> = []; + for (const c of contacts) { + const conversationId = c.address; + const messages = await this.smsStoreService.getMessages(conversationId); + messages.forEach((m) => rows.push(this.messageToRow(m, conversationId))); + } + this.csvExportService.downloadCsv('sms-all-messages', rows, columns); + }; + + void run(); + } + + private messageToRow(m: Message, conversationId: string, bodyHtmlOverride?: string): Record { + const timestampMs = Number(m.timestamp); + const dateIso = (m.date ?? new Date(timestampMs)).toISOString(); + const direction = m.type === 2 || m.type === 4 ? 'sent' : m.type === 1 || m.type === 3 ? 'received' : ''; + const bodyHtml = bodyHtmlOverride ?? m.body; + + return { + conversationId, + contactName: m.contactName, + direction, + type: m.type, + timestampMs, + dateIso, + bodyText: this.csvExportService.htmlToText(bodyHtml), + bodyHtml + }; + } + + private getSelectedColumns(fields: ExportOptions['fields']): string[] { + const allColumns = [ + 'conversationId', + 'contactName', + 'direction', + 'type', + 'timestampMs', + 'dateIso', + 'bodyText', + 'bodyHtml' + ] as const; + + return allColumns.filter(col => fields[col as keyof ExportOptions['fields']]); + } + + trackByMessage(_index: number, message: Message): string { + // Some backups can contain duplicate timestamps; include a few fields for stability. + return `${Number(message?.timestamp)}:${message?.type}:${message?.body?.length ?? 0}`; } } diff --git a/src/app/message-type.pipe.spec.ts b/src/app/message-type.pipe.spec.ts index 8803cf8..41aa31a 100644 --- a/src/app/message-type.pipe.spec.ts +++ b/src/app/message-type.pipe.spec.ts @@ -1,6 +1,3 @@ -/* tslint:disable:no-unused-variable */ - -import { TestBed, async } from '@angular/core/testing'; import { MessageTypePipe } from './message-type.pipe'; describe('MessageTypePipe', () => { diff --git a/src/app/message-type.pipe.ts b/src/app/message-type.pipe.ts index 17c8c0a..67f9144 100644 --- a/src/app/message-type.pipe.ts +++ b/src/app/message-type.pipe.ts @@ -1,7 +1,8 @@ import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ - name: 'messageType' + name: 'messageType', + standalone: false }) export class MessageTypePipe implements PipeTransform { diff --git a/src/app/settings/settings.component.css b/src/app/settings/settings.component.css index e69de29..4f5cadc 100644 --- a/src/app/settings/settings.component.css +++ b/src/app/settings/settings.component.css @@ -0,0 +1,126 @@ +.\:host, +:host { + display: block; + height: 100%; + overflow-y: auto; + -webkit-overflow-scrolling: touch; +} + +.settings-container { + display: flex; + justify-content: center; + align-items: flex-start; + padding: 40px 20px; + min-height: 100%; + background: var(--bg); +} + +.settings-card { + width: 100%; + max-width: 720px; + min-height: 300px; +} + +/* Keep inner padding symmetric (MDL defaults can vary with nested content) */ +.settings-card .mdl-card__supporting-text { + padding-left: 16px; + padding-right: 16px; + box-sizing: border-box; +} + +.storage-stats { + display: flex; + flex-wrap: wrap; + column-gap: 18px; + row-gap: 6px; +} + +.mdl-card__title { + background: linear-gradient(135deg, rgba(59, 130, 246, 1) 0%, var(--primary) 100%); + color: white; + display: flex; + align-items: flex-start; + justify-content: space-between; + min-height: 56px; + padding: 12px 16px; +} + +.mdl-card__title-text { + margin: 0; + line-height: 1.2; +} + +.settings-close { + color: rgba(255, 255, 255, 0.95); + align-self: flex-start; +} + +.settings-close:hover { + background: rgba(255, 255, 255, 0.16); +} + +.settings-description { + color: #666; + font-size: 14px; + margin-bottom: 24px; +} + +.country-select-wrapper { + margin-top: 0; +} + +.country-select-wrapper .setting-label { + margin-bottom: 0; +} + +.setting-label { + font-size: 16px; + font-weight: 700; + color: #333; + margin: 0 0 2px; +} + +.setting-help { + font-size: 13px; + color: #757575; + margin-top: 0; + margin-bottom: 16px; +} + +.advanced-details { + margin-top: 18px; + border: 1px solid rgba(0, 0, 0, 0.10); + border-radius: 12px; + background: rgba(0, 0, 0, 0.02); + overflow: hidden; +} + +.advanced-summary { + list-style: none; + cursor: pointer; + padding: 12px 14px; + display: flex; + align-items: baseline; + justify-content: space-between; + gap: 12px; +} + +.advanced-summary::-webkit-details-marker { + display: none; +} + +.advanced-summary-chevron { + font-size: 20px; + line-height: 1; + color: rgba(0, 0, 0, 0.55); + transform: rotate(0deg); + transition: transform 120ms ease; +} + +.advanced-details[open] .advanced-summary-chevron { + transform: rotate(180deg); +} + +.advanced-body { + padding: 0 14px 14px; +} diff --git a/src/app/settings/settings.component.html b/src/app/settings/settings.component.html index be2a829..1702f0e 100644 --- a/src/app/settings/settings.component.html +++ b/src/app/settings/settings.component.html @@ -1,10 +1,100 @@ -

Settings

-
-

These settings affect how the backup file is processed.

-
-
- -
- \ No newline at end of file +
+
+
+

Settings

+ + + +
+
+
+

Country Code

+

Select your country to properly format phone numbers.

+ +
+ +
+ +

Advanced

+ +
+
+
+

Import (SMS)

+

Choose how SMS backups are imported. For very large backups, the desktop streaming importer is recommended. This affects the SMS button in the header.

+
+ + +
+ Tauri mode is only available in the installed desktop app. +
+
+ +
+

Storage (IndexedDB)

+

Persist imported messages locally so reloads are instant. Recommended for large imports.

+ +
+ Stored conversations: {{ dbThreadCount.toLocaleString() }} + Stored messages: {{ dbMessageCount.toLocaleString() }} +
+
+ + +
+

This clears stored SMS messages and also clears any currently loaded contacts.

+ +
+

Export

+

Download the currently loaded data as CSV.

+
+ + +
+
+
+
+
+ +
+
+
\ No newline at end of file diff --git a/src/app/settings/settings.component.spec.ts b/src/app/settings/settings.component.spec.ts index 62ac394..57c7c5d 100644 --- a/src/app/settings/settings.component.spec.ts +++ b/src/app/settings/settings.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { RouterTestingModule } from '@angular/router/testing'; +import { CsvExportService } from '../csv-export.service'; +import { SmsStoreService } from '../sms-store.service'; import { SettingsComponent } from './settings.component'; describe('SettingsComponent', () => { let component: SettingsComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ SettingsComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [RouterTestingModule], + declarations: [ SettingsComponent ], + providers: [SmsStoreService, CsvExportService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(SettingsComponent); diff --git a/src/app/settings/settings.component.ts b/src/app/settings/settings.component.ts index 7989458..3f57675 100644 --- a/src/app/settings/settings.component.ts +++ b/src/app/settings/settings.component.ts @@ -1,15 +1,168 @@ import { Component, OnInit } from '@angular/core'; +import { Subscription } from 'rxjs'; + +import { CsvExportService } from '../csv-export.service'; +import { SmsStoreService } from '../sms-store.service'; +import { Message } from '../message'; +import { Contact } from '../contact'; +import { SmsDbService } from '../sms-db.service'; +import { VcfStoreService } from '../vcf-store.service'; @Component({ selector: 'app-settings', templateUrl: './settings.component.html', - styleUrls: ['./settings.component.css'] + styleUrls: ['./settings.component.css'], + standalone: false }) export class SettingsComponent implements OnInit { + messagesLoaded: boolean = false; + private loadingSubscription: Subscription; + indexedDbEnabled: boolean = true; + dbThreadCount: number = 0; + dbMessageCount: number = 0; + clearingDb: boolean = false; + smsImportMode: 'auto' | 'browser' | 'tauri' = 'tauri'; + isTauriRuntime: boolean = false; - constructor() { } + constructor( + private smsStoreService: SmsStoreService, + private csvExportService: CsvExportService, + private smsDbService: SmsDbService, + private vcfStoreService: VcfStoreService + ) { } ngOnInit() { + this.loadingSubscription = this.smsStoreService.messagesLoaded$ + .subscribe((loaded) => (this.messagesLoaded = loaded)); + this.indexedDbEnabled = this.smsStoreService.getIndexedDbEnabled(); + this.smsImportMode = this.smsStoreService.getSmsImportMode(); + this.isTauriRuntime = this.detectTauri(); + + // If the store defaulted to 'tauri' but we're not running in a Tauri runtime, + // fall back to 'auto' so the UI doesn't select a disabled option. + if (this.smsImportMode === 'tauri' && !this.isTauriRuntime) { + this.smsImportMode = 'auto'; + this.smsStoreService.setSmsImportMode('auto'); + } + + this.refreshDbStats(); + } + + private detectTauri(): boolean { + const protocol = (window?.location?.protocol ?? '').toLowerCase(); + if (protocol === 'tauri:' || protocol === 'asset:') { + return true; + } + const host = (window?.location?.hostname ?? '').toLowerCase(); + // Tauri v2 commonly uses https://tauri.localhost in production builds. + if (host === 'tauri.localhost' || host.endsWith('.tauri.localhost')) { + return true; + } + // In dev (devUrl), protocol/host can look like a normal http://localhost page. + // Prefer checking for injected globals. + const w = window as any; + if (typeof w?.__TAURI__ !== 'undefined' || typeof w?.__TAURI_INTERNALS__ !== 'undefined') { + return true; + } + const ua = (navigator?.userAgent ?? '').toLowerCase(); + return ua.includes('tauri'); + } + + ngOnDestroy() { + this.loadingSubscription?.unsubscribe(); + } + + async refreshDbStats(): Promise { + try { + const stats = await this.smsDbService.getStats(); + this.dbThreadCount = stats.threadCount; + this.dbMessageCount = stats.messageCount; + } catch { + this.dbThreadCount = 0; + this.dbMessageCount = 0; + } + } + + onIndexedDbEnabledChanged(): void { + this.smsStoreService.setIndexedDbEnabled(this.indexedDbEnabled); + } + + onSmsImportModeChanged(): void { + const mode = this.smsImportMode; + if (mode === 'tauri' && !this.isTauriRuntime) { + this.smsImportMode = 'auto'; + this.smsStoreService.setSmsImportMode('auto'); + return; + } + this.smsStoreService.setSmsImportMode(mode); + } + + async clearIndexedDb(): Promise { + if (this.clearingDb) { + return; + } + this.clearingDb = true; + try { + await this.smsStoreService.clearIndexedDb(); + // Also clear any in-memory state. + await this.smsStoreService.clearAllMessages(); + this.smsStoreService.broadcastMessagesLoaded(false); + await this.vcfStoreService.clearAllContacts(); + this.vcfStoreService.broadcastMessagesLoaded(false); + await this.refreshDbStats(); + } finally { + this.clearingDb = false; + } + } + + async exportAllMessages(): Promise { + const contacts = await this.smsStoreService.getAllContacts(); + const rows: Array> = []; + for (const c of contacts) { + const conversationId = c.address; + const messages = await this.smsStoreService.getMessages(conversationId); + messages.forEach((m) => { + const timestampMs = Number(m.timestamp); + const dateIso = (m.date ?? new Date(timestampMs)).toISOString(); + const direction = m.type === 2 || m.type === 4 ? 'sent' : m.type === 1 || m.type === 3 ? 'received' : ''; + rows.push({ + conversationId, + contactName: m.contactName, + direction, + type: m.type, + timestampMs, + dateIso, + bodyText: this.csvExportService.htmlToText(m.body), + bodyHtml: m.body + }); + }); + } + + this.csvExportService.downloadCsv('sms-backup-messages', rows, [ + 'conversationId', + 'contactName', + 'direction', + 'type', + 'timestampMs', + 'dateIso', + 'bodyText', + 'bodyHtml' + ]); + } + + async exportContacts(): Promise { + const contacts: Contact[] = await this.smsStoreService.getAllContacts(); + const rows = contacts.map((c) => ({ + name: c.name, + address: c.address, + messageCount: c.messageCount + })); + + this.csvExportService.downloadCsv('sms-backup-contacts', rows, [ + 'name', + 'address', + 'messageCount' + ]); } } diff --git a/src/app/sms-db.service.ts b/src/app/sms-db.service.ts new file mode 100644 index 0000000..0225f46 --- /dev/null +++ b/src/app/sms-db.service.ts @@ -0,0 +1,179 @@ +import { Injectable } from '@angular/core'; +import Dexie, { Table } from 'dexie'; + +export type DbMessage = { + id?: number; + threadId: string; + dateMs: number; + timestamp: string; + type: number; + contactName: string | null; + body: string; +}; + +export type DbThread = { + threadId: string; + contactName: string | null; + messageCount: number; + lastDateMs: number; +}; + +class SmsBackupViewerDb extends Dexie { + messages!: Table; + threads!: Table; + + constructor() { + super('sms-backup-viewer'); + + // Version 1 schema + this.version(1).stores({ + // ++id for efficient inserts; compound index supports fetching a conversation in order. + messages: '++id, threadId, dateMs, [threadId+dateMs]', + // threadId is the normalized contact address. + threads: 'threadId, lastDateMs' + }); + } +} + +@Injectable({ + providedIn: 'root' +}) +export class SmsDbService { + private db = new SmsBackupViewerDb(); + + async getStats(): Promise<{ threadCount: number; messageCount: number }> { + const [threadCount, messageCount] = await Promise.all([ + this.db.threads.count(), + this.db.messages.count() + ]); + return { threadCount, messageCount }; + } + + async clearAll(): Promise { + await this.db.transaction('rw', this.db.messages, this.db.threads, async () => { + await this.db.messages.clear(); + await this.db.threads.clear(); + }); + } + + async ingestBatch(items: Array<{ threadId: string; message: { timestamp: string; type: number; contactName: string | null; body: string; dateMs: number } }>): Promise { + if (!items?.length) { + return; + } + + const messages: DbMessage[] = []; + const threadAgg = new Map(); + + for (const item of items) { + const { threadId, message } = item; + messages.push({ + threadId, + timestamp: message.timestamp, + type: message.type, + contactName: message.contactName ?? null, + body: message.body, + dateMs: message.dateMs + }); + + const existing = threadAgg.get(threadId); + if (!existing) { + threadAgg.set(threadId, { + messageCount: 1, + lastDateMs: message.dateMs, + contactName: message.contactName ?? null + }); + } else { + existing.messageCount += 1; + existing.lastDateMs = Math.max(existing.lastDateMs, message.dateMs); + if (!existing.contactName && message.contactName) { + existing.contactName = message.contactName; + } + } + } + + await this.db.transaction('rw', this.db.messages, this.db.threads, async () => { + await this.db.messages.bulkAdd(messages); + + const threadIds = Array.from(threadAgg.keys()); + const existingThreads = await this.db.threads.bulkGet(threadIds); + + const upserts: DbThread[] = []; + for (let i = 0; i < threadIds.length; i++) { + const threadId = threadIds[i]; + const agg = threadAgg.get(threadId)!; + const existing = existingThreads[i]; + + if (!existing) { + upserts.push({ + threadId, + contactName: agg.contactName, + messageCount: agg.messageCount, + lastDateMs: agg.lastDateMs + }); + } else { + upserts.push({ + threadId, + contactName: existing.contactName ?? agg.contactName, + messageCount: (existing.messageCount ?? 0) + agg.messageCount, + lastDateMs: Math.max(existing.lastDateMs ?? 0, agg.lastDateMs) + }); + } + } + + await this.db.threads.bulkPut(upserts); + }); + } + + async getThreads(): Promise { + return this.db.threads.orderBy('lastDateMs').reverse().toArray(); + } + + async getMessagesForThread(threadId: string): Promise { + return this.db.messages.where('[threadId+dateMs]').between([threadId, Dexie.minKey], [threadId, Dexie.maxKey]).toArray(); + } + + async getLatestMessagesForThread(threadId: string, limit: number): Promise { + if (!limit || limit <= 0) { + return []; + } + const rows = await this.db.messages + .where('[threadId+dateMs]') + .between([threadId, Dexie.minKey], [threadId, Dexie.maxKey]) + .reverse() + .limit(limit) + .toArray(); + return rows.reverse(); + } + + async getMessagesBefore(threadId: string, beforeDateMs: number, limit: number): Promise { + if (!limit || limit <= 0) { + return []; + } + const upper = Math.max(0, (beforeDateMs ?? 0) - 1); + const rows = await this.db.messages + .where('[threadId+dateMs]') + .between([threadId, Dexie.minKey], [threadId, upper]) + .reverse() + .limit(limit) + .toArray(); + return rows.reverse(); + } + + async updateThreadNames(nameByThreadId: Map): Promise { + const entries = Array.from(nameByThreadId.entries()).filter(([_, name]) => !!name); + if (!entries.length) { + return; + } + + await this.db.transaction('rw', this.db.threads, async () => { + for (const [threadId, name] of entries) { + await this.db.threads.update(threadId, { contactName: name }); + } + }); + } + + async hasAnyData(): Promise { + const count = await this.db.threads.count(); + return count > 0; + } +} diff --git a/src/app/sms-loader.service.spec.ts b/src/app/sms-loader.service.spec.ts index 1f53c7c..15d7a23 100644 --- a/src/app/sms-loader.service.spec.ts +++ b/src/app/sms-loader.service.spec.ts @@ -1,16 +1,16 @@ -/* tslint:disable:no-unused-variable */ +import { TestBed } from '@angular/core/testing'; -import { TestBed, async, inject } from '@angular/core/testing'; import { SmsLoaderService } from './sms-loader.service'; describe('SmsLoaderService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [SmsLoaderService] + providers: [SmsLoaderService], }); }); - it('should ...', inject([SmsLoaderService], (service: SmsLoaderService) => { + it('should be created', () => { + const service = TestBed.inject(SmsLoaderService); expect(service).toBeTruthy(); - })); + }); }); diff --git a/src/app/sms-loader.service.ts b/src/app/sms-loader.service.ts index dfc467c..c4f34c4 100644 --- a/src/app/sms-loader.service.ts +++ b/src/app/sms-loader.service.ts @@ -8,8 +8,17 @@ export class SmsLoaderService { constructor() { } private handleError(error: any): Promise { - console.error('An error occurred', error); // for demo purposes only - return Promise.reject(error.message || error); + // FileReader failures often come through as ProgressEvent without a message. + if (error && typeof error === 'object' && (error as any).type === 'error') { + console.error('Failed to read file'); + return Promise.reject(new Error('Failed to read file in browser (FileReader error).')); + } + if (error && typeof error === 'object' && (error as any).type === 'abort') { + return Promise.reject(new Error('File read was aborted.')); + } + + console.error('An error occurred', error); + return Promise.reject(error?.message || error); } //55296 >= X <= 57343 @@ -27,7 +36,7 @@ export class SmsLoaderService { } getLoadedMessages(): Promise { - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { resolve(this.messages); }).catch(this.handleError); } @@ -38,68 +47,121 @@ export class SmsLoaderService { return txt.value; } - loadSMSFile(file: File): Promise { - this.messages = new Array(); - let reader: FileReader = new FileReader(); - let parser: any = new DOMParser(); - let xmlDoc: any; - - reader.readAsText(file, 'UTF-8'); - - return new Promise((resolve, reject) => { - reader.onload = (event: any) => { // Shouldn't need 'any' but this fixes an issue with TS definitions - var cleanedText = this.cleanString(event.target.result); - xmlDoc = parser.parseFromString(cleanedText, 'text/xml'); - for (let sms of xmlDoc.getElementsByTagName('sms')) { - this.messages.push({ - //contactNumber: sms.getAttribute('address'), - contactAddress: sms.getAttribute('address'), - contactName: sms.getAttribute('contact_name'), - type: parseInt(sms.getAttribute('type')), - timestamp: sms.getAttribute('date'), - date: new Date(parseInt(sms.getAttribute('date'))), - body: sms.getAttribute('body') - }); + private getElementsByLocalName(doc: any, localName: string): Element[] { + const out = new Set(); + const addAll = (list: any) => { + if (!list || typeof list.length !== 'number') { + return; + } + for (let i = 0; i < list.length; i++) { + out.add(list[i]); + } + }; + + // Exact tag name match (common case) + addAll(doc.getElementsByTagName?.(localName)); + // Namespace-tolerant match (e.g. ) + addAll(doc.getElementsByTagNameNS?.('*', localName)); + // Some exporters might use uppercase tags + addAll(doc.getElementsByTagName?.(localName.toUpperCase())); + addAll(doc.getElementsByTagNameNS?.('*', localName.toUpperCase())); + + return Array.from(out); + } + + private parseSmsBackupXml(xmlText: string): Message[] { + const parser: any = new DOMParser(); + const xmlDoc: any = parser.parseFromString(xmlText, 'text/xml'); + + // Detect parse errors (browser-dependent, but widely supported). + if (xmlDoc.getElementsByTagName('parsererror')?.length) { + throw new Error('Invalid XML file. Expected an SMS Backup & Restore XML backup.'); + } + + const smsNodes = this.getElementsByLocalName(xmlDoc, 'sms'); + const mmsNodes = this.getElementsByLocalName(xmlDoc, 'mms'); + if (smsNodes.length === 0 && mmsNodes.length === 0) { + const rootTag = xmlDoc?.documentElement?.tagName ?? '(unknown root)'; + throw new Error( + `No or entries found in XML (root: <${rootTag}>). Is this the correct SMS Backup & Restore XML?` + ); + } + + const out: Message[] = []; + + for (let sms of smsNodes) { + out.push({ + contactAddress: sms.getAttribute('address'), + contactName: sms.getAttribute('contact_name'), + type: parseInt(sms.getAttribute('type')), + timestamp: sms.getAttribute('date'), + date: new Date(parseInt(sms.getAttribute('date'))), + body: sms.getAttribute('body') + }); + } + + for (let mms of mmsNodes) { + let contactAddress: string = ''; + let body: string = ''; + let type: number = 3; + + for (let addr of this.getElementsByLocalName(mms, 'addr')) { + if (addr.getAttribute('type') == '137' || contactAddress == 'insert-address-token') { + contactAddress = addr.getAttribute('address'); + } + if (contactAddress == 'insert-address-token') { + type = 4; + } } - for (let mms of xmlDoc.getElementsByTagName('mms')) { - let contactAddress:string = ""; - let body:string =""; - let type:number = 3; - for (let addr of mms.getElementsByTagName('addr')) { - if ((addr.getAttribute('type') == "137") || - (contactAddress == 'insert-address-token')) - { - contactAddress = addr.getAttribute('address'); - } - if (contactAddress == 'insert-address-token') - { - type = 4; - } - } - for (let part of mms.getElementsByTagName('part')) { - if (part.getAttribute('ct') == "image/jpeg") - { - body = body + ''; - } - if (part.getAttribute('ct') == "text/plain") - { - body = body + '
'+ part.getAttribute('text') + '
'; - } - } - this.messages.push({ - contactAddress: contactAddress, - contactName: mms.getAttribute('contact_name'), - type: type, - timestamp: mms.getAttribute('date'), - date: new Date(parseInt(mms.getAttribute('date'))), - body: body - }); + + for (let part of this.getElementsByLocalName(mms, 'part')) { + if (part.getAttribute('ct') == 'image/jpeg') { + body = + body + + ''; + } + if (part.getAttribute('ct') == 'text/plain') { + body = body + '
' + (part.getAttribute('text') ?? '') + '
'; + } } - resolve(); + + out.push({ + contactAddress, + contactName: mms.getAttribute('contact_name'), + type, + timestamp: mms.getAttribute('date'), + date: new Date(parseInt(mms.getAttribute('date'))), + body + }); } - - }).catch(this.handleError); + return out; + } + + private readFileAsText(file: File): Promise { + return new Promise((resolve, reject) => { + const reader = new FileReader(); + reader.onload = (event: any) => resolve(event?.target?.result ?? ''); + reader.onerror = (e) => reject(e); + reader.onabort = (e) => reject(e); + reader.readAsText(file); + }); + } + + loadSMSFile(file: File): Promise { + return this.loadSMSFiles([file]); + } + + async loadSMSFiles(files: File[]): Promise { + this.messages = new Array(); + for (const file of files) { + const rawText = await this.readFileAsText(file); + const cleanedText = this.cleanString(rawText); + const parsed = this.parseSmsBackupXml(cleanedText); + this.messages.push(...parsed); + } } } diff --git a/src/app/sms-loader/sms-loader.component.css b/src/app/sms-loader/sms-loader.component.css index e69de29..31b51fc 100644 --- a/src/app/sms-loader/sms-loader.component.css +++ b/src/app/sms-loader/sms-loader.component.css @@ -0,0 +1,110 @@ +.file-upload-button { + display: inline-flex; + align-items: center; + justify-content: center; +} + + +.mdl-button--raised.mdl-button--accent.file-upload-button--tauri { + background: linear-gradient(180deg, #34d399 0%, #16a34a 100%) !important; + color: #fff !important; + border-color: rgba(22, 163, 74, 0.55); +} + +.mdl-button--raised.mdl-button--accent.file-upload-button--tauri:hover { + background: linear-gradient(180deg, #6ee7b7 0%, #16a34a 100%) !important; +} + +.mdl-button--raised.mdl-button--accent.file-upload-button--tauri:active { + background: linear-gradient(180deg, #22c55e 0%, #15803d 100%) !important; +} + +.file-upload-button .material-icons { + margin-right: 8px; +} + +input[type="file"] { + display: none; +} + +.loader-inline { + display: inline-flex; + align-items: center; + gap: 8px; +} + +.tauri-path-row { + display: flex; + align-items: center; + gap: 8px; + flex-wrap: wrap; +} + +.tauri-path-row input[type="text"] { + flex: 1 1 auto; + min-width: 180px; + padding: 8px; + box-sizing: border-box; +} + +.tauri-path-actions { + display: inline-flex; + align-items: center; + gap: 8px; + flex: 0 0 auto; +} + +.load-status { + margin-top: 8px; + padding: 8px 10px; + border-radius: 8px; + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + line-height: 1.2; + border: 1px solid rgba(0, 0, 0, 0.12); + background: rgba(0, 0, 0, 0.03); +} + +.load-status .status-icon { + font-size: 18px; +} + +.load-status.idle { + color: rgba(0, 0, 0, 0.75); +} + +.load-status.busy { + color: rgba(0, 0, 0, 0.85); + background: rgba(33, 150, 243, 0.08); + border-color: rgba(33, 150, 243, 0.25); +} + +.load-status.ok { + color: rgba(0, 0, 0, 0.85); + background: rgba(76, 175, 80, 0.10); + border-color: rgba(76, 175, 80, 0.25); +} + +.load-status.error { + color: rgba(0, 0, 0, 0.9); + background: rgba(244, 67, 54, 0.10); + border-color: rgba(244, 67, 54, 0.25); +} + +.progress { + margin-top: 6px; + height: 6px; + border-radius: 999px; + overflow: hidden; + background: rgba(0, 0, 0, 0.10); + border: 1px solid rgba(0, 0, 0, 0.08); +} + +.progress-fill { + height: 100%; + background: rgba(33, 150, 243, 0.65); + width: 0%; + transition: width 120ms linear; +} diff --git a/src/app/sms-loader/sms-loader.component.html b/src/app/sms-loader/sms-loader.component.html index 357c2a1..d13b118 100644 --- a/src/app/sms-loader/sms-loader.component.html +++ b/src/app/sms-loader/sms-loader.component.html @@ -1,4 +1,27 @@ - - \ No newline at end of file +
+ + + +
\ No newline at end of file diff --git a/src/app/sms-loader/sms-loader.component.spec.ts b/src/app/sms-loader/sms-loader.component.spec.ts index 993f047..4d9aa62 100644 --- a/src/app/sms-loader/sms-loader.component.spec.ts +++ b/src/app/sms-loader/sms-loader.component.spec.ts @@ -1,20 +1,24 @@ -/* tslint:disable:no-unused-variable */ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; -import { By } from '@angular/platform-browser'; -import { DebugElement } from '@angular/core'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule } from '@angular/forms'; import { SmsLoaderComponent } from './sms-loader.component'; +import { SmsLoaderService } from '../sms-loader.service'; +import { SmsStoreService } from '../sms-store.service'; describe('SmsLoaderComponent', () => { let component: SmsLoaderComponent; let fixture: ComponentFixture; let filename : string; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ SmsLoaderComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + imports: [FormsModule], + declarations: [ SmsLoaderComponent ], + providers: [SmsLoaderService, SmsStoreService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(SmsLoaderComponent); diff --git a/src/app/sms-loader/sms-loader.component.ts b/src/app/sms-loader/sms-loader.component.ts index fec03fc..55986de 100644 --- a/src/app/sms-loader/sms-loader.component.ts +++ b/src/app/sms-loader/sms-loader.component.ts @@ -1,39 +1,392 @@ import { Component, OnInit, EventEmitter, Output } from '@angular/core'; +import { Subscription } from 'rxjs'; import { SmsLoaderService } from '../sms-loader.service'; import { SmsStoreService } from '../sms-store.service'; +import { Message } from '../message'; +import { LoaderStatusUpdate } from '../loader-status'; @Component({ selector: 'sms-loader', templateUrl: './sms-loader.component.html', - styleUrls: ['./sms-loader.component.css'] + styleUrls: ['./sms-loader.component.css'], + standalone: false }) export class SmsLoaderComponent implements OnInit { @Output() onLoaded = new EventEmitter(); + @Output() statusChanged = new EventEmitter(); sampleText: string = 'not loaded'; loaded: boolean = false; - filename : string =''; + status: 'idle' | 'busy' | 'ok' | 'error' = 'idle'; + isTauri: boolean = false; + tauriPath: string = ''; + private unlistenFns: Array<() => void> = []; + private importModeSub?: Subscription; + importMode: 'auto' | 'browser' | 'tauri' = 'auto'; + parsedCount: number = 0; + totalBytes: number = 0; + bytesRead: number = 0; constructor( private smsLoaderService: SmsLoaderService, private smsStoreService: SmsStoreService ) { } ngOnInit() { + this.isTauri = this.detectTauri(); + this.importMode = this.smsStoreService.getSmsImportMode(); + this.importModeSub = this.smsStoreService.smsImportMode$.subscribe((mode) => { + this.importMode = mode; + }); + this.status = 'idle'; + this.emitStatus(); + } + + ngOnDestroy() { + this.importModeSub?.unsubscribe(); + this.unlistenFns.forEach((fn) => { + try { + fn(); + } catch { + // ignore + } + }); + this.unlistenFns = []; + } + + private detectTauri(): boolean { + // Robust detection for installed desktop builds and devUrl. + const protocol = (window?.location?.protocol ?? '').toLowerCase(); + if (protocol === 'tauri:' || protocol === 'asset:') { + return true; + } + const host = (window?.location?.hostname ?? '').toLowerCase(); + if (host === 'tauri.localhost' || host.endsWith('.tauri.localhost')) { + return true; + } + const w = window as any; + if (typeof w?.__TAURI__ !== 'undefined' || typeof w?.__TAURI_INTERNALS__ !== 'undefined') { + return true; + } + const ua = (navigator?.userAgent ?? '').toLowerCase(); + return ua.includes('tauri'); + } + + private async tauriInvoke(command: string, args?: Record): Promise { + try { + // Import core at runtime; this stays behind an isTauri guard. + const core = await import('@tauri-apps/api/core') as any; + const invoke = core.invoke as (cmd: string, args?: Record) => Promise; + return invoke(command, args ?? {}); + } catch { + return Promise.reject(new Error('Tauri invoke not available.')); + } + } + + private async tauriListen(eventName: string, handler: (payload: T) => void): Promise { + try { + // Import event at runtime; this stays behind an isTauri guard. + const ev = await import('@tauri-apps/api/event') as any; + const listen = ev.listen as (name: string, cb: (event: any) => void) => Promise<() => void>; + const unlisten = await listen(eventName, (event) => handler((event as any)?.payload)); + if (typeof unlisten === 'function') { + this.unlistenFns.push(unlisten); + } + } catch { + throw new Error('Tauri event.listen not available.'); + } + } + + private resetProgress(): void { + this.parsedCount = 0; + this.totalBytes = 0; + this.bytesRead = 0; + } + + get progressPercent(): number { + if (!this.totalBytes || this.totalBytes <= 0) { + return 0; + } + const pct = (this.bytesRead / this.totalBytes) * 100; + if (!Number.isFinite(pct)) { + return 0; + } + return Math.max(0, Math.min(100, pct)); + } + + private progressText(): string { + if (this.totalBytes > 0 && this.bytesRead >= 0) { + return `Parsing... ${this.formatBytes(this.bytesRead)} / ${this.formatBytes(this.totalBytes)} (${this.parsedCount.toLocaleString()} msgs)`; + } + return `Parsing... (${this.parsedCount.toLocaleString()} msgs)`; + } + + async browseForTauriPath(): Promise { + if (!this.isTauri) { + return; + } + try { + const { open } = await import('@tauri-apps/plugin-dialog') as any; + const selected = await open({ + multiple: false, + directory: false, + title: 'Select SMS Backup XML', + filters: [{ name: 'XML files', extensions: ['xml'] }] + }); + if (typeof selected === 'string' && selected.trim()) { + this.tauriPath = selected; + } + } catch (e) { + this.sampleText = `Failed to open file picker: ${(e as any)?.message ?? String(e)}`; + this.status = 'error'; + this.emitStatus(); + } + } + + async browseAndLoadFromTauriPath(): Promise { + if (!this.isTauri) { + this.sampleText = 'Not running under Tauri.'; + this.status = 'error'; + this.emitStatus(); + return; + } + try { + const { open } = await import('@tauri-apps/plugin-dialog') as any; + const selected = await open({ + multiple: false, + directory: false, + title: 'Select SMS Backup XML', + filters: [{ name: 'XML files', extensions: ['xml'] }] + }); + if (typeof selected === 'string' && selected.trim()) { + this.tauriPath = selected; + await this.loadFromTauriPath(); + } + } catch (e) { + this.sampleText = `Failed to open file picker: ${(e as any)?.message ?? String(e)}`; + this.status = 'error'; + this.emitStatus(); + } + } + + async loadFromTauriPath(): Promise { + if (!this.isTauri) { + this.sampleText = 'Not running under Tauri.'; + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + return; + } + const path = (this.tauriPath || '').trim(); + if (!path) { + this.sampleText = 'Enter a file path to an XML backup.'; + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + return; + } + + this.sampleText = 'Starting Tauri parse...'; + this.status = 'busy'; + this.loaded = false; + this.resetProgress(); + this.emitStatus(); + this.smsStoreService.beginIngest({ persistToIndexedDb: true, clearIndexedDb: true }); + + // Clear prior listeners for repeated loads. + this.unlistenFns.forEach((fn) => { + try { + fn(); + } catch { + // ignore + } + }); + this.unlistenFns = []; + + type ParsedMessage = { + contactAddress: string; + contactName?: string | null; + type: number; + timestamp: string; + dateMs: number; + body: string; + }; + type ParseBatch = { + messages: ParsedMessage[]; + bytesRead: number; + totalBytes: number; + parsedCount: number; + }; + type ParseProgress = { + bytesRead: number; + totalBytes: number; + parsedCount: number; + }; + type ParseDone = { + bytesRead: number; + totalBytes: number; + parsedCount: number; + }; + + await this.tauriListen('sms_parse_batch', (batch) => { + if (!batch?.messages?.length) { + return; + } + this.bytesRead = batch.bytesRead ?? this.bytesRead; + this.totalBytes = batch.totalBytes ?? this.totalBytes; + this.parsedCount = batch.parsedCount ?? this.parsedCount; + + const msgs: Message[] = batch.messages.map((m) => { + return { + contactAddress: m.contactAddress, + contactName: (m.contactName ?? null) as any, + type: m.type, + timestamp: m.timestamp, + date: new Date(m.dateMs), + body: m.body + } as any; + }); + this.smsStoreService.ingestMessagesBatch(msgs); + this.sampleText = this.progressText(); + this.status = 'busy'; + this.emitStatus(); + }); + + await this.tauriListen('sms_parse_progress', (p) => { + this.bytesRead = p?.bytesRead ?? this.bytesRead; + this.totalBytes = p?.totalBytes ?? this.totalBytes; + this.parsedCount = p?.parsedCount ?? this.parsedCount; + this.sampleText = this.progressText(); + this.status = 'busy'; + this.emitStatus(); + }); + + await this.tauriListen('sms_parse_error', (err) => { + this.sampleText = `Failed to load: ${String(err ?? 'Unknown error')}`; + this.status = 'error'; + this.loaded = false; + this.emitStatus(); + this.onLoaded.emit(false); + }); + + await this.tauriListen('sms_parse_done', async (done) => { + this.bytesRead = done?.bytesRead ?? this.bytesRead; + this.totalBytes = done?.totalBytes ?? this.totalBytes; + this.parsedCount = done?.parsedCount ?? this.parsedCount; + await this.smsStoreService.finishIngestAsync(); + this.smsStoreService.broadcastMessagesLoaded(true); + this.sampleText = `Loaded! (${this.parsedCount.toLocaleString()} msgs)`; + this.status = 'ok'; + this.loaded = true; + this.emitStatus(); + this.onLoaded.emit(true); + }); + + try { + await this.tauriInvoke('start_parse_sms_backup', { path }); + this.sampleText = this.progressText(); + this.status = 'busy'; + this.emitStatus(); + } catch (e) { + this.sampleText = `Failed to start parse: ${(e as any)?.message ?? String(e)}`; + this.status = 'error'; + this.loaded = false; + this.emitStatus(); + this.onLoaded.emit(false); + } + } + + private formatBytes(bytes: number): string { + if (!Number.isFinite(bytes) || bytes < 0) { + return String(bytes); + } + const units = ['B', 'KB', 'MB', 'GB', 'TB']; + let value = bytes; + let unitIndex = 0; + while (value >= 1024 && unitIndex < units.length - 1) { + value /= 1024; + unitIndex++; + } + return `${value.toFixed(value >= 10 || unitIndex === 0 ? 0 : 1)} ${units[unitIndex]}`; } fileChange(fileEvent: any): void { - console.log(fileEvent.target.files); - console.log(this); - var file: File; - if (fileEvent.target.files && fileEvent.target.files.length >= 1) { - file = fileEvent.target.files[0]; - this.smsLoaderService.loadSMSFile(file).then(result => { - this.sampleText = 'Loaded!'; - this.onLoaded.emit(true); - this.loaded = true; - this.filename = ''; - console.log(this); - }); + if (this.isTauri && this.importMode === 'tauri') { + this.sampleText = 'Browser upload disabled in Settings. Switch Import mode to Auto or Browser.'; + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + this.loaded = false; + if (fileEvent?.target) { + fileEvent.target.value = ''; + } + return; } + this.sampleText = 'Loading...'; + this.status = 'busy'; + this.loaded = false; + this.emitStatus(); + + const selected: File[] = Array.from(fileEvent?.target?.files ?? []); + if (selected.length >= 1) { + + // Guard: very large XML backups (especially with MMS media) are not feasible to parse + // in-browser with DOMParser + full-string FileReader. + const MAX_BYTES = 250 * 1024 * 1024; // 250 MB + const tooLarge = selected.find((f) => f.size > MAX_BYTES); + if (tooLarge) { + if (this.isTauri) { + this.sampleText = `File too large for browser upload (${this.formatBytes(tooLarge.size)}). Use "Load from path (Tauri)" for large backups.`; + } else { + this.sampleText = `File too large for in-browser import (${this.formatBytes(tooLarge.size)}). For large backups, use the desktop app (Tauri) and "Load from path". If you must use the browser, export without media to reduce the file size.`; + } + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + this.loaded = false; + if (fileEvent?.target) { + fileEvent.target.value = ''; + } + return; + } + + this.sampleText = `Loading 1/${selected.length}...`; + this.emitStatus(); + this.smsLoaderService + .loadSMSFiles(selected) + .then(() => { + this.sampleText = 'Loaded!'; + this.status = 'ok'; + this.emitStatus(); + this.onLoaded.emit(true); + this.loaded = true; + }) + .catch((err) => { + this.sampleText = 'Failed to load'; + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + this.loaded = false; + console.error('Failed to load SMS backup file', err); + }) + .finally(() => { + // Allow selecting the same file again. + if (fileEvent?.target) { + fileEvent.target.value = ''; + } + }); + } + } + + private emitStatus(): void { + this.statusChanged.emit({ + source: 'sms', + status: this.status, + text: this.sampleText, + updatedAt: Date.now(), + progressPercent: this.status === 'busy' ? this.progressPercent : undefined, + bytesRead: this.bytesRead, + totalBytes: this.totalBytes, + parsedCount: this.parsedCount + }); } } diff --git a/src/app/sms-store.service.spec.ts b/src/app/sms-store.service.spec.ts index 278ac21..1c76568 100644 --- a/src/app/sms-store.service.spec.ts +++ b/src/app/sms-store.service.spec.ts @@ -1,16 +1,16 @@ -/* tslint:disable:no-unused-variable */ +import { TestBed } from '@angular/core/testing'; -import { TestBed, async, inject } from '@angular/core/testing'; import { SmsStoreService } from './sms-store.service'; describe('SmsStoreService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [SmsStoreService] + providers: [SmsStoreService], }); }); - it('should ...', inject([SmsStoreService], (service: SmsStoreService) => { + it('should be created', () => { + const service = TestBed.inject(SmsStoreService); expect(service).toBeTruthy(); - })); + }); }); diff --git a/src/app/sms-store.service.ts b/src/app/sms-store.service.ts index c4a472d..0fff30f 100644 --- a/src/app/sms-store.service.ts +++ b/src/app/sms-store.service.ts @@ -1,8 +1,9 @@ -import { Injectable } from '@angular/core'; -import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import { Injectable, NgZone } from '@angular/core'; +import { BehaviorSubject } from 'rxjs'; import { Message } from './message'; import { Contact } from './contact'; +import { SmsDbService } from './sms-db.service'; import awesomePhone from 'awesome-phonenumber'; @@ -14,26 +15,228 @@ export class SmsStoreService { messageMap: Map; countryCode: string; messagesLoaded: boolean; + private useIndexedDb: boolean; + private ingestChain: Promise; + private indexedDbEnabled: boolean; + private smsImportMode: 'auto' | 'browser' | 'tauri' = 'tauri'; - constructor() { + constructor(private smsDbService: SmsDbService, private ngZone: NgZone) { this.messagesLoaded = false; this.countryCode = 'US'; + this.useIndexedDb = false; + this.ingestChain = Promise.resolve(); + this.indexedDbEnabled = this.readIndexedDbEnabled(); + this.smsImportMode = this.readSmsImportMode(); + this._smsImportModeSource.next(this.smsImportMode); + } + + private readSmsImportMode(): 'auto' | 'browser' | 'tauri' { + try { + const raw = window?.localStorage?.getItem('smsBackupViewer.smsImportMode'); + if (raw === 'browser' || raw === 'tauri' || raw === 'auto') { + return raw; + } + return 'tauri'; + } catch { + return 'tauri'; + } + } + + private readIndexedDbEnabled(): boolean { + try { + const raw = window?.localStorage?.getItem('smsBackupViewer.indexedDbEnabled'); + if (raw === null || raw === undefined) { + return true; + } + return raw === 'true'; + } catch { + return true; + } + } + + setIndexedDbEnabled(enabled: boolean): void { + this.indexedDbEnabled = !!enabled; + try { + window?.localStorage?.setItem('smsBackupViewer.indexedDbEnabled', String(this.indexedDbEnabled)); + } catch { + // ignore + } + } + + getIndexedDbEnabled(): boolean { + return this.indexedDbEnabled; + } + + private _smsImportModeSource = new BehaviorSubject<'auto' | 'browser' | 'tauri'>('tauri'); + smsImportMode$ = this._smsImportModeSource.asObservable(); + + getSmsImportMode(): 'auto' | 'browser' | 'tauri' { + return this.smsImportMode; + } + + setSmsImportMode(mode: 'auto' | 'browser' | 'tauri'): void { + this.smsImportMode = mode; + try { + window?.localStorage?.setItem('smsBackupViewer.smsImportMode', String(mode)); + } catch { + // ignore + } + this._smsImportModeSource.next(this.smsImportMode); + } + + async restoreFromIndexedDbIfEnabled(): Promise { + if (!this.indexedDbEnabled) { + return false; + } + const hasAny = await this.smsDbService.hasAnyData(); + if (!hasAny) { + return false; + } + this.useIndexedDb = true; + this.messagesLoaded = true; + return true; + } + + beginIngest(options?: { persistToIndexedDb?: boolean; clearIndexedDb?: boolean }): void { + const persistToIndexedDb = options?.persistToIndexedDb === true; + this.useIndexedDb = persistToIndexedDb; + + // Always clear in-memory state. + this.messages = []; + this.messageMap = new Map(); + this.contacts = []; + this.messagesLoaded = false; + + this.ingestChain = Promise.resolve(); + + if (persistToIndexedDb && options?.clearIndexedDb !== false) { + // Ensure clear happens before the first batch write. + this.ingestChain = this.smsDbService.clearAll().then(() => undefined); + } + } + + ingestMessagesBatch(messages: Message[]): void { + if (!messages?.length) { + return; + } + + if (this.useIndexedDb) { + const batch = messages.map((message) => { + const threadId = this.normalizeContactAddress(message.contactAddress); + const dateMs = message.date?.getTime?.() ?? Number(message.timestamp) ?? 0; + return { + threadId, + message: { + timestamp: message.timestamp, + type: message.type, + contactName: message.contactName ?? null, + body: message.body, + dateMs + } + }; + }); + this.ingestChain = this.ingestChain + .then(() => this.smsDbService.ingestBatch(batch)) + .catch((e) => { + console.error('IndexedDB ingest failed', e); + }); + return; + } + + if (!this.messages) { + this.messages = []; + } + if (!this.messageMap) { + this.messageMap = new Map(); + } + for (const message of messages) { + this.messages.push(message); + const contactAddress = this.normalizeContactAddress(message.contactAddress); + let mapEntry = this.messageMap.get(contactAddress); + if (!mapEntry) { + mapEntry = []; + this.messageMap.set(contactAddress, mapEntry); + } + mapEntry.push(message); + } + } + + private normalizeContactAddress(raw: string): string { + let phone = new awesomePhone(raw, this.countryCode); + let contactAddress: string = phone.getNumber('international'); + if (!contactAddress) { + contactAddress = raw; + } + return contactAddress; + } + + finishIngest(): void { + if (this.useIndexedDb) { + // Legacy sync API: prefer finishIngestAsync() in DB mode. + this.messagesLoaded = true; + return; + } + if (!this.messageMap) { + this.messageMap = new Map(); + } + this.messageMap.forEach((value: Message[], key: string) => { + value = value.sort((message1, message2) => message1.date.getTime() - message2.date.getTime()); + this.messageMap.set(key, value); + }); + + this.contacts = []; + this.messageMap.forEach((value: Message[], key: string) => { + let contactName = value[0]?.contactName; + this.contacts.push({ + name: (contactName != '(Unknown)') ? contactName : null, + address: key as string, + messageCount: value.length + }); + }); + + this.messagesLoaded = true; + } + + async finishIngestAsync(): Promise { + if (this.useIndexedDb) { + await this.ingestChain; + this.messagesLoaded = true; + return; + } + this.finishIngest(); + } + + isUsingIndexedDb(): boolean { + return this.useIndexedDb; } areMessagesLoaded(): Promise { return Promise.resolve(this.messagesLoaded); } - changeCountry(countryCode: string): Promise { - return new Promise((resolve, reject) => { + changeCountry(countryCode: string): Promise { + return new Promise((resolve, reject) => { if (this.countryCode != countryCode) { this.countryCode = countryCode; - if (this.messagesLoaded) { - this.loadAllMessages(this.messages); + if (this.useIndexedDb && this.messagesLoaded) { + // Re-grouping DB-backed conversations would require re-writing threadIds. + // Keep it simple: country affects formatting; for persisted data, re-import is recommended. + this.broadcastMessagesLoaded(true); + resolve(); + return; + } + if (this.messagesLoaded) { + this.loadAllMessages(this.messages).then(() => { + this.broadcastMessagesLoaded(true); + resolve(); + }); + } else { + resolve(); } + } else { + resolve(); } - resolve(); }); } @@ -50,7 +253,11 @@ export class SmsStoreService { messagesLoaded$ = this._messagesLoadedSource.asObservable(); // Service command broadcastMessagesLoaded(messagesLoaded: boolean) { - this._messagesLoadedSource.next(messagesLoaded); + // Some producers (notably Tauri event callbacks) can run outside Angular's zone. + // Emitting inside NgZone ensures subscribers trigger change detection immediately. + this.ngZone.run(() => { + this._messagesLoadedSource.next(messagesLoaded); + }); } // Observable source @@ -59,7 +266,9 @@ export class SmsStoreService { contactClicked$ = this._contactClickedSource.asObservable(); // Service command broadcastContactClicked(contactClicked: Contact) { - this._contactClickedSource.next(contactClicked); + this.ngZone.run(() => { + this._contactClickedSource.next(contactClicked); + }); } @@ -69,46 +278,67 @@ export class SmsStoreService { this.contacts = new Array(); return new Promise((resolve, reject) => { this.messages = messages; - for (let message of messages) { - let mapEntry; - let phone = new awesomePhone(message.contactAddress, this.countryCode); - let contactAddress: string = phone.getNumber('international'); - if (!contactAddress) { - contactAddress = message.contactAddress; + + // Process messages in chunks to avoid freezing UI + const CHUNK_SIZE = 500; + let index = 0; + + const processChunk = () => { + const endIndex = Math.min(index + CHUNK_SIZE, messages.length); + + for (let i = index; i < endIndex; i++) { + let message = messages[i]; + let mapEntry; + let phone = new awesomePhone(message.contactAddress, this.countryCode); + let contactAddress: string = phone.getNumber('international'); + if (!contactAddress) { + contactAddress = message.contactAddress; + } + + if(!(mapEntry = this.messageMap.get(contactAddress))) { + mapEntry = new Array(); + mapEntry.push(message); + this.messageMap.set(contactAddress, mapEntry); + } else { + mapEntry.push(message); + } } - //console.log(`contact: ${contactAddress}`); - if(!(mapEntry = this.messageMap.get(contactAddress))) { - mapEntry = new Array(); - mapEntry.push(message); - this.messageMap.set(contactAddress, mapEntry); + + index = endIndex; + + if (index < messages.length) { + // More messages to process, schedule next chunk + setTimeout(processChunk, 0); } else { - mapEntry.push(message); - } - } - //sort by timestamp - this.messageMap.forEach(( value: Message[], key: string) => { - value = value.sort((message1, message2) => message1.date.getTime() - message2.date.getTime()); - this.messageMap.set(key, value); - }); - this.messageMap.forEach((value: Message[], key: string) => { - let contactName = value[0].contactName; - this.contacts.push({ - name: (contactName != '(Unknown)') ? contactName : null, - address: key as string, - messageCount: value.length - }); - }); + // All messages processed, now sort and create contacts + this.messageMap.forEach(( value: Message[], key: string) => { + value = value.sort((message1, message2) => message1.date.getTime() - message2.date.getTime()); + this.messageMap.set(key, value); + }); + + this.messageMap.forEach((value: Message[], key: string) => { + let contactName = value[0].contactName; + this.contacts.push({ + name: (contactName != '(Unknown)') ? contactName : null, + address: key as string, + messageCount: value.length + }); + }); - resolve(); + this.messagesLoaded = true; + resolve(); + } + }; + + processChunk(); }); } - clearAllMessages(): Promise { - return new Promise((resolve, reject) => { + clearAllMessages(): Promise { + return new Promise((resolve, reject) => { this.messageMap = new Map(); this.messages = new Array(); this.messagesLoaded = false; - console.log('Cleared in service: ' + JSON.stringify(this.messages)); resolve(); }); } @@ -116,47 +346,129 @@ export class SmsStoreService { // Get all messages for all contacts getAllMessages(): Promise> { return new Promise((resolve, reject) => { - resolve(this.messageMap); + // Not supported in DB mode without loading everything into memory. + resolve(this.messageMap); }); } + // Get the raw loaded messages (flat list) + getRawMessages(): Promise { + return Promise.resolve(this.messages ?? []); + } + // this.contacts = [...messageMap.keys()]; // need to target ES6 for this to work getAllContacts(): Promise { - return new Promise((resolve, reject) => { - resolve(this.contacts); + if (!this.useIndexedDb) { + return new Promise((resolve, reject) => { + resolve(this.contacts); + }); + } + return this.smsDbService.getThreads().then((threads) => { + return threads.map((t) => { + return { + name: t.contactName, + address: t.threadId, + messageCount: t.messageCount + } as Contact; + }); }); } // Get the messages for a specific contact getMessages(contactId: string): Promise { - let returnMessages: Message[]; - return new Promise((resolve, reject) => { - returnMessages = this.messageMap.get(contactId); - resolve(returnMessages); + if (!this.useIndexedDb) { + let returnMessages: Message[]; + return new Promise((resolve, reject) => { + returnMessages = this.messageMap.get(contactId); + resolve(returnMessages); + }); + } + return this.smsDbService.getMessagesForThread(contactId).then((rows) => { + return rows.map((r) => { + return { + contactAddress: contactId, + contactName: (r.contactName ?? null) as any, + timestamp: r.timestamp, + type: r.type, + body: r.body, + date: new Date(r.dateMs) + } as any; + }); + }); + } + + getLatestMessages(contactId: string, limit: number): Promise { + const dbStart = performance.now(); + if (!this.useIndexedDb) { + const all = this.messageMap?.get(contactId) ?? []; + const sliced = limit && limit > 0 ? all.slice(Math.max(0, all.length - limit)) : all; + console.debug('[perf] getLatestMessages (in-memory) time (ms):', performance.now() - dbStart); + return Promise.resolve(sliced); + } + return this.smsDbService.getLatestMessagesForThread(contactId, limit).then((rows) => { + const mapped = rows.map((r) => { + return { + contactAddress: contactId, + contactName: (r.contactName ?? null) as any, + timestamp: r.timestamp, + type: r.type, + body: r.body, + date: new Date(r.dateMs) + } as any; + }); + console.debug('[perf] getLatestMessages (db) time (ms):', performance.now() - dbStart); + return mapped; + }); + } + + getOlderMessages(contactId: string, beforeDateMs: number, limit: number): Promise { + if (!this.useIndexedDb) { + const all = this.messageMap?.get(contactId) ?? []; + if (!all.length) { + return Promise.resolve([]); + } + const cutoff = beforeDateMs ?? all[0]?.date?.getTime?.() ?? Number(all[0]?.timestamp) ?? 0; + const older = all.filter((m) => (m.date?.getTime?.() ?? Number(m.timestamp) ?? 0) < cutoff); + const sliced = limit && limit > 0 ? older.slice(Math.max(0, older.length - limit)) : older; + return Promise.resolve(sliced); + } + return this.smsDbService.getMessagesBefore(contactId, beforeDateMs, limit).then((rows) => { + return rows.map((r) => { + return { + contactAddress: contactId, + contactName: (r.contactName ?? null) as any, + timestamp: r.timestamp, + type: r.type, + body: r.body, + date: new Date(r.dateMs) + } as any; + }); }); } fillContactNames(contactMap: Map): Promise { return new Promise((resolve, reject) => { - //console.log(this.contacts); - this.contacts.forEach(function(contact) - { - let name: string; - console.log(contact.address); - name = contactMap.get(contact.address); - if (name) - { - contact.name = name; - console.log(contact.name); - } - else - { - console.log("not found"); - } - }); + if (this.useIndexedDb) { + void this.smsDbService.updateThreadNames(contactMap); + resolve(); + return; + } + this.contacts.forEach(function(contact) + { + let name: string; + name = contactMap.get(contact.address); + if (name) + { + contact.name = name; + } + }); resolve(); }); } + + async clearIndexedDb(): Promise { + await this.smsDbService.clearAll(); + } } diff --git a/src/app/toast.component.ts b/src/app/toast.component.ts new file mode 100644 index 0000000..b4a62c5 --- /dev/null +++ b/src/app/toast.component.ts @@ -0,0 +1,76 @@ +import { Component, OnDestroy } from '@angular/core'; +import { ToastService, Toast } from './toast.service'; +import { Subscription } from 'rxjs'; + +@Component({ + selector: 'app-toast', + standalone: true, + template: ` +
+
+
+
{{ t.message }}
+
+ +
+
+
+
+ `, + styles: [ + ` + .toast-container { + position: fixed; + right: 16px; + bottom: 18px; + display: flex; + flex-direction: column; + gap: 8px; + z-index: 9999; + pointer-events: none; + } + .toast { + pointer-events: auto; + background: rgba(0,0,0,0.8); + color: white; + padding: 10px 14px; + border-radius: 8px; + box-shadow: 0 4px 12px rgba(0,0,0,0.15); + max-width: 420px; + font-size: 13px; + } + .toast-body { display: flex; align-items: center; justify-content: space-between; gap: 8px; } + .toast-message { flex: 1 1 auto; } + .toast-actions { flex: 0 0 auto; } + .toast-action { background: rgba(255,255,255,0.08); color: white; border: none; padding: 6px 8px; border-radius: 6px; cursor: pointer; } + `, + ], +}) +export class ToastComponent implements OnDestroy { + toasts: Toast[] = []; + private sub: Subscription; + + constructor(private toastService: ToastService) { + this.sub = this.toastService.toasts$.subscribe((t) => this.pushToast(t)); + } + + private pushToast(t: Toast) { + this.toasts.push(t); + if (t.timeoutMs && t.timeoutMs > 0) { + setTimeout(() => this.removeToast(t.id), t.timeoutMs); + } + } + + onAction(id: string) { + this.toastService.performAction(id); + this.removeToast(id); + } + + removeToast(id: string) { + this.toasts = this.toasts.filter((x) => x.id !== id); + } + + ngOnDestroy(): void { + this.sub.unsubscribe(); + } +} diff --git a/src/app/toast.service.ts b/src/app/toast.service.ts new file mode 100644 index 0000000..7cea305 --- /dev/null +++ b/src/app/toast.service.ts @@ -0,0 +1,43 @@ +import { Injectable } from '@angular/core'; +import { Subject } from 'rxjs'; + +export interface Toast { + id: string; + message: string; + timeoutMs?: number; + actionLabel?: string; +} + +@Injectable({ providedIn: 'root' }) +export class ToastService { + private _toasts = new Subject(); + toasts$ = this._toasts.asObservable(); + private actions = new Map void | Promise>(); + + show(message: string, timeoutMs: number = 5000) { + const t: Toast = { id: String(Date.now()) + Math.random().toString(36).slice(2, 8), message, timeoutMs }; + this._toasts.next(t); + return t.id; + } + + showWithAction(message: string, actionLabel: string, action: () => void | Promise, timeoutMs: number = 7000) { + const t: Toast = { id: String(Date.now()) + Math.random().toString(36).slice(2, 8), message, timeoutMs, actionLabel }; + this.actions.set(t.id, action); + this._toasts.next(t); + return t.id; + } + + performAction(id: string) { + const action = this.actions.get(id); + if (action) { + try { + const result = action(); + if (result && typeof (result as Promise).then === 'function') { + (result as Promise).catch(() => {}); + } + } finally { + this.actions.delete(id); + } + } + } +} diff --git a/src/app/vcf-loader.service.spec.ts b/src/app/vcf-loader.service.spec.ts index 967f43e..3b0fd1b 100644 --- a/src/app/vcf-loader.service.spec.ts +++ b/src/app/vcf-loader.service.spec.ts @@ -1,16 +1,16 @@ -import { TestBed, inject } from '@angular/core/testing'; - +import { TestBed } from '@angular/core/testing'; import { VcfLoaderService } from './vcf-loader.service'; describe('VcfLoaderService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [VcfLoaderService] + providers: [VcfLoaderService], }); }); - it('should be created', inject([VcfLoaderService], (service: VcfLoaderService) => { + it('should be created', () => { + const service = TestBed.inject(VcfLoaderService); expect(service).toBeTruthy(); - })); + }); }); diff --git a/src/app/vcf-loader.service.ts b/src/app/vcf-loader.service.ts index b638068..6a4fe93 100644 --- a/src/app/vcf-loader.service.ts +++ b/src/app/vcf-loader.service.ts @@ -15,7 +15,7 @@ export class VcfLoaderService { reader.readAsText(file, 'UTF-8'); - return new Promise((resolve, reject) => { + return new Promise((resolve, reject) => { reader.onload = (event: any) => { // Shouldn't need 'any' but this fixes an issue with TS definitions this.vcards = event.target.result; resolve(this.vcards); diff --git a/src/app/vcf-loader/vcf-loader.component.css b/src/app/vcf-loader/vcf-loader.component.css index e69de29..7633de3 100644 --- a/src/app/vcf-loader/vcf-loader.component.css +++ b/src/app/vcf-loader/vcf-loader.component.css @@ -0,0 +1,58 @@ +.file-upload-button { + display: inline-flex; + align-items: center; + justify-content: center; +} + +.file-upload-button .material-icons { + margin-right: 8px; +} + +input[type="file"] { + display: none; +} + +.loader-inline { + display: inline-flex; + align-items: center; + gap: 8px; +} + +.load-status { + margin-top: 8px; + padding: 8px 10px; + border-radius: 8px; + display: flex; + align-items: center; + gap: 8px; + font-size: 13px; + line-height: 1.2; + border: 1px solid rgba(0, 0, 0, 0.12); + background: rgba(0, 0, 0, 0.03); +} + +.load-status .status-icon { + font-size: 18px; +} + +.load-status.idle { + color: rgba(0, 0, 0, 0.75); +} + +.load-status.busy { + color: rgba(0, 0, 0, 0.85); + background: rgba(33, 150, 243, 0.08); + border-color: rgba(33, 150, 243, 0.25); +} + +.load-status.ok { + color: rgba(0, 0, 0, 0.85); + background: rgba(76, 175, 80, 0.10); + border-color: rgba(76, 175, 80, 0.25); +} + +.load-status.error { + color: rgba(0, 0, 0, 0.9); + background: rgba(244, 67, 54, 0.10); + border-color: rgba(244, 67, 54, 0.25); +} diff --git a/src/app/vcf-loader/vcf-loader.component.html b/src/app/vcf-loader/vcf-loader.component.html index f5d0897..076e0d2 100644 --- a/src/app/vcf-loader/vcf-loader.component.html +++ b/src/app/vcf-loader/vcf-loader.component.html @@ -1,4 +1,15 @@ - - \ No newline at end of file +
+ + +
\ No newline at end of file diff --git a/src/app/vcf-loader/vcf-loader.component.spec.ts b/src/app/vcf-loader/vcf-loader.component.spec.ts index c1d4ddc..700b819 100644 --- a/src/app/vcf-loader/vcf-loader.component.spec.ts +++ b/src/app/vcf-loader/vcf-loader.component.spec.ts @@ -1,17 +1,21 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; import { VcfLoaderComponent } from './vcf-loader.component'; +import { VcfLoaderService } from '../vcf-loader.service'; describe('VcfLoaderComponent', () => { let component: VcfLoaderComponent; let fixture: ComponentFixture; - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ VcfLoaderComponent ] + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ VcfLoaderComponent ], + providers: [VcfLoaderService], + schemas: [CUSTOM_ELEMENTS_SCHEMA], }) .compileComponents(); - })); + }); beforeEach(() => { fixture = TestBed.createComponent(VcfLoaderComponent); diff --git a/src/app/vcf-loader/vcf-loader.component.ts b/src/app/vcf-loader/vcf-loader.component.ts index 8592d4b..657ce7d 100644 --- a/src/app/vcf-loader/vcf-loader.component.ts +++ b/src/app/vcf-loader/vcf-loader.component.ts @@ -1,35 +1,71 @@ import { Component, OnInit, EventEmitter, Output } from '@angular/core'; import { VcfLoaderService } from '../vcf-loader.service'; +import { LoaderStatusUpdate } from '../loader-status'; @Component({ selector: 'vcf-loader', templateUrl: './vcf-loader.component.html', - styleUrls: ['./vcf-loader.component.css'] + styleUrls: ['./vcf-loader.component.css'], + standalone: false }) export class VcfLoaderComponent implements OnInit { @Output() onLoaded = new EventEmitter(); - sampleText: String = 'not loaded'; + @Output() statusChanged = new EventEmitter(); + sampleText: string = 'not loaded'; loaded: boolean = false; + status: 'idle' | 'busy' | 'ok' | 'error' = 'idle'; constructor( private VcfLoaderService: VcfLoaderService, ) { } ngOnInit() { + this.status = 'idle'; + this.emitStatus(); } fileChange(fileEvent: any): void { - console.log(fileEvent.target.files); + this.sampleText = 'Loading...'; + this.status = 'busy'; + this.loaded = false; + this.emitStatus(); + var file: File; if (fileEvent.target.files && fileEvent.target.files.length >= 1) { file = fileEvent.target.files[0]; - this.VcfLoaderService.loadVCFFile(file).then(result => { - this.sampleText = 'Loaded!'; - this.onLoaded.emit(true); - this.loaded = true; + this.VcfLoaderService + .loadVCFFile(file) + .then(() => { + this.sampleText = 'Loaded!'; + this.status = 'ok'; + this.emitStatus(); + this.onLoaded.emit(true); + this.loaded = true; + }) + .catch((err) => { + this.sampleText = 'Failed to load'; + this.status = 'error'; + this.emitStatus(); + this.onLoaded.emit(false); + this.loaded = false; + console.error('Failed to load VCF file', err); + }) + .finally(() => { + if (fileEvent?.target) { + fileEvent.target.value = ''; + } }); } } + + private emitStatus(): void { + this.statusChanged.emit({ + source: 'vcf', + status: this.status, + text: this.sampleText, + updatedAt: Date.now() + }); + } } diff --git a/src/app/vcf-store.service.spec.ts b/src/app/vcf-store.service.spec.ts index 201abd8..06ab65f 100644 --- a/src/app/vcf-store.service.spec.ts +++ b/src/app/vcf-store.service.spec.ts @@ -1,15 +1,16 @@ -import { TestBed, inject } from '@angular/core/testing'; +import { TestBed } from '@angular/core/testing'; import { VcfStoreService } from './vcf-store.service'; describe('VcfStoreService', () => { beforeEach(() => { TestBed.configureTestingModule({ - providers: [VcfStoreService] + providers: [VcfStoreService], }); }); - it('should be created', inject([VcfStoreService], (service: VcfStoreService) => { + it('should be created', () => { + const service = TestBed.inject(VcfStoreService); expect(service).toBeTruthy(); - })); + }); }); diff --git a/src/app/vcf-store.service.ts b/src/app/vcf-store.service.ts index b21c78c..87b3cca 100644 --- a/src/app/vcf-store.service.ts +++ b/src/app/vcf-store.service.ts @@ -1,7 +1,6 @@ import { Injectable } from '@angular/core'; -import {BehaviorSubject} from 'rxjs/BehaviorSubject'; +import { BehaviorSubject } from 'rxjs'; import { Contact } from './contact'; -var vCard = require('vcf'); import awesomePhone from 'awesome-phonenumber'; @Injectable() @@ -27,10 +26,15 @@ export class VcfStoreService { { this.countryCode = countryCode; if (this.contacts) { - this.loadAllContacts(this.contacts); + this.loadAllContacts(this.contacts).then(() => { + resolve(); + }); + } else { + resolve(); } + } else { + resolve(); } - resolve(); }); } @@ -64,39 +68,40 @@ export class VcfStoreService { if (!contactNum) { contactNum = tel["_data"]; } - console.log(contactNum + ":" + name); this.contactMap.set(contactNum, name); } } loadAllContacts(contacts: string): Promise { - this.contacts = contacts; + this.contacts = contacts; this.contactMap = new Map(); return new Promise((resolve, reject) => { - /*console.log(contacts);*/ - var arcontacts = vCard.parse(contacts); - var content = ''; - for (let contact of arcontacts) { - var tel; - var tels; - var i; - tels = contact.get('tel'); - if (tels) - { - if (tels.length) - { - for (i = 0; i < tels.length; i++) { - this.addContacttoMap(tels[i], contact.get('fn')); - } - } - else - { - this.addContacttoMap(tels, contact.get('fn')) - } - } - } - this.contactsLoaded = true; - resolve(); + // Defer pulling in the vcf parsing library until a VCF is actually loaded. + import('vcf') + .then((vcfMod: any) => { + const parseFn = vcfMod?.parse ?? vcfMod?.default?.parse; + if (typeof parseFn !== 'function') { + throw new Error('VCF parser not available'); + } + return parseFn(contacts); + }) + .then((arcontacts: any[]) => { + for (let contact of arcontacts) { + let tels = contact.get('tel'); + if (tels) { + if (tels.length) { + for (let i = 0; i < tels.length; i++) { + this.addContacttoMap(tels[i], contact.get('fn')); + } + } else { + this.addContacttoMap(tels, contact.get('fn')); + } + } + } + this.contactsLoaded = true; + resolve(); + }) + .catch((err) => reject(err)); }); } @@ -104,7 +109,6 @@ export class VcfStoreService { return new Promise((resolve, reject) => { this.contactMap = new Map(); this.contactsLoaded = false; - console.log('Cleared in service: '); resolve(); }); } diff --git a/src/app/version.ts b/src/app/version.ts new file mode 100644 index 0000000..c3d3f0d --- /dev/null +++ b/src/app/version.ts @@ -0,0 +1,5 @@ +// This file is auto-generated by scripts/update-version.mjs +// Do not edit manually - changes will be overwritten at build time. +export const APP_VERSION = '0.26.0'; +export const APP_BUILD_TIME = '2026-01-23T23:00:29.748Z'; +export const APP_GIT_COMMIT = '852c97f'; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index b7f639a..7cbf0e9 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -1,7 +1,8 @@ // The file contents for the current environment will overwrite these during build. -// The build system defaults to the dev environment which uses `environment.ts`, but if you do -// `ng build --env=prod` then `environment.prod.ts` will be used instead. -// The list of which env maps to which file can be found in `.angular-cli.json`. +// The build system defaults to the dev environment which uses `environment.ts`, but if you build +// with the production configuration (`ng build --configuration production`) then +// `environment.prod.ts` will be used instead. +// The list of which env maps to which file can be found in `angular.json`. export const environment = { production: false diff --git a/src/index.html b/src/index.html index 4c09d05..97fd428 100644 --- a/src/index.html +++ b/src/index.html @@ -2,7 +2,7 @@ - SmsBackupReader + SMS Backup Viewer diff --git a/src/index.tauri.html b/src/index.tauri.html new file mode 100644 index 0000000..1e8fa75 --- /dev/null +++ b/src/index.tauri.html @@ -0,0 +1,16 @@ + + + + + SMS Backup Viewer + + + + + + + + + Loading... + + diff --git a/src/main.ts b/src/main.ts index 91ec6da..1e13545 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,5 +1,5 @@ import { enableProdMode } from '@angular/core'; -import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; +import { platformBrowser } from '@angular/platform-browser'; import { AppModule } from './app/app.module'; import { environment } from './environments/environment'; @@ -8,5 +8,5 @@ if (environment.production) { enableProdMode(); } -platformBrowserDynamic().bootstrapModule(AppModule) - .catch(err => console.log(err)); +platformBrowser().bootstrapModule(AppModule) + .catch(err => console.error(err)); diff --git a/src/styles.css b/src/styles.css index e93524d..69fbac4 100644 --- a/src/styles.css +++ b/src/styles.css @@ -1,80 +1,291 @@ /* You can add global styles to this file, and also import other style files */ -input[type="file"] { - display: none; + +/* Global styles */ +:root { + --bg: #e9edf5; + --surface: #ffffff; + --surface-2: #f4f6fb; + --text: rgba(0, 0, 0, 0.87); + --muted: rgba(0, 0, 0, 0.60); + --border: rgba(0, 0, 0, 0.14); + --primary: #2563eb; + --primary-weak: rgba(37, 99, 235, 0.12); + --success: #16a34a; + --danger: #dc2626; + --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.08); + --shadow-md: 0 10px 30px rgba(0, 0, 0, 0.12); + --radius: 14px; + --gap: 12px; + /* Narrower contacts column */ + --contacts-width: clamp(270px, 22vw, 340px); } -country-select { - margin-left: auto; - margin-right: auto; - text-align: center; +body { + font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif; + color: var(--text); + background: var(--bg); + margin: 0; + padding: 0; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +.mdl-layout__content { + background: var(--bg); +} + +/* Buttons (MDL overrides for a modern look) */ +.mdl-button { + border-radius: 14px; + text-transform: none; + font-weight: 600; + letter-spacing: 0.01em; + min-height: 38px; + padding: 0 14px; + transition: transform 0.14s ease, box-shadow 0.14s ease, background-color 0.14s ease, border-color 0.14s ease; +} + +.mdl-button--raised { + box-shadow: var(--shadow-sm) !important; + border: 1px solid var(--border); } -message-list { +.mdl-button--raised:hover { + transform: translateY(-1px); + box-shadow: var(--shadow-md) !important; +} +.mdl-button--raised.mdl-button--colored, +.mdl-button--raised.mdl-button--accent { + background: linear-gradient(180deg, rgba(59, 130, 246, 1) 0%, var(--primary) 100%) !important; + color: #fff !important; + border-color: rgba(37, 99, 235, 0.40); } -contact-list { +/* Neutral raised buttons */ +.mdl-button--raised:not(.mdl-button--colored):not(.mdl-button--accent) { + background: var(--surface) !important; + color: var(--text) !important; +} +/* Text/outline accent buttons (e.g. Settings) */ +.mdl-button--accent:not(.mdl-button--raised), +.mdl-button--colored:not(.mdl-button--raised), +.mdl-button--primary:not(.mdl-button--raised) { + color: var(--primary) !important; + border: 1px solid rgba(37, 99, 235, 0.28); + background: rgba(255, 255, 255, 0.70); +} + +.mdl-button--accent:not(.mdl-button--raised):hover, +.mdl-button--colored:not(.mdl-button--raised):hover, +.mdl-button--primary:not(.mdl-button--raised):hover { + background: var(--primary-weak); +} + +.mdl-button:focus { + outline: none; +} + +.mdl-button:focus-visible { + box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.25) !important; +} + +.mdl-button[disabled], +.mdl-button.is-disabled { + opacity: 0.55; + cursor: not-allowed; + transform: none !important; + box-shadow: none !important; +} + +/* Consistent spacing for horizontal button groups */ +.button-row { + display: flex; + flex-wrap: wrap; + gap: 10px; + align-items: center; +} + +input[type="file"] { + display: none; +} + +country-select { + margin-left: auto; + margin-right: auto; + text-align: center; } .page-content { overflow: hidden; width: 100%; + flex: 1 1 auto; + min-height: 0; + position: relative; + padding: var(--gap); + box-sizing: border-box; } +/* Contact list styling */ .contacts { - overflow-y: scroll; - background: #f5f2f0; + overflow-y: auto; + background: var(--surface); position: absolute; - width: 30%; - /*padding: 10px;*/ - left:0; - top:0; - bottom:0; + width: var(--contacts-width); + left: var(--gap); + top: var(--gap); + bottom: var(--gap); + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow-sm); } +/* Messages area styling */ .messages { - overflow-y: scroll; - /*background: #fff123;*/ + overflow-y: auto; + background: var(--surface); position: absolute; - width: 70%; - /*padding: 10px;*/ - right:0; - top:0; - bottom:0; + left: calc(var(--gap) + var(--contacts-width) + var(--gap)); + right: var(--gap); + top: var(--gap); + bottom: var(--gap); + width: auto; + padding: 18px 18px 24px; + box-sizing: border-box; + border: 1px solid var(--border); + border-radius: var(--radius); + box-shadow: var(--shadow-sm); } + +/* List item height fixes */ .mdl-list__item--two-line { - height: auto!important; + height: auto !important; + min-height: 72px; } + .mdl-list__item--two-line .mdl-list__item-primary-content { - height: auto!important; + height: auto !important; } + +/* Message bubble styling - improved chat-like appearance */ .message-sent { - background: #FFF123; - text-align: right; + background: rgba(22, 163, 74, 0.12); + text-align: right; + border-radius: 16px; + margin: 8px 0; + padding: 12px 16px; + max-width: 70%; + margin-left: auto; + box-shadow: var(--shadow-sm); + border: 1px solid rgba(22, 163, 74, 0.18); } .message-received { - background: #DDD123; - text-align: left; + background: var(--surface-2); + text-align: left; + border-radius: 16px; + margin: 8px 0; + padding: 12px 16px; + max-width: 70%; + margin-right: auto; + box-shadow: var(--shadow-sm); + border: 1px solid var(--border); } - -.mms-received,.mms-sent { - height: auto!important; +/* MMS message styling */ +.mms-received, .mms-sent { + height: auto !important; } -li.mms-received > span,li.mms-sent > span -{ - height: auto!important; + +li.mms-received > span, li.mms-sent > span { + height: auto !important; } +/* Image sizing */ img { - max-height: 40%; - max-width: 40%; -} + max-height: 300px; + max-width: 100%; + border-radius: 4px; + margin: 8px 0; +} + +/* Selected contact styling - improved contrast */ +.selected-contact { + background: var(--primary-weak) !important; + color: var(--text) !important; + border-left: none; + border: 1px solid rgba(37, 99, 235, 0.20); +} + +/* Active/hover states */ +.contact-item:hover { + background: rgba(37, 99, 235, 0.06); + transition: background 0.2s ease; +} + +/* Responsive design for mobile devices */ +@media (max-width: 768px) { + .contacts { + width: 100%; + position: relative; + border-right: none; + left: 0; + top: 0; + bottom: 0; + border-radius: var(--radius); + max-height: 40vh; + } + + .messages { + width: 100%; + position: relative; + left: 0; + right: 0; + top: 0; + bottom: 0; + padding: 14px; + border-radius: var(--radius); + min-height: 50vh; + } + + .page-content { + display: flex; + flex-direction: column; + } + + .message-sent, + .message-received { + max-width: 85%; + } +} + +/* Smooth transitions */ +.contact-item, +.message-sent, +.message-received { + transition: all 0.2s ease; +} + +/* Improve scrollbar styling for webkit browsers */ +.contacts::-webkit-scrollbar, +.messages::-webkit-scrollbar { + width: 8px; +} + +.contacts::-webkit-scrollbar-track, +.messages::-webkit-scrollbar-track { + background: #f1f1f1; +} + +.contacts::-webkit-scrollbar-thumb, +.messages::-webkit-scrollbar-thumb { + background: #c1c1c1; + border-radius: 4px; +} -.selected-contact{ - background:rgb(76, 76, 151); - color: #BBB +.contacts::-webkit-scrollbar-thumb:hover, +.messages::-webkit-scrollbar-thumb:hover { + background: #a8a8a8; } diff --git a/src/test.ts b/src/test.ts deleted file mode 100644 index 1631789..0000000 --- a/src/test.ts +++ /dev/null @@ -1,20 +0,0 @@ -// This file is required by karma.conf.js and loads recursively all the .spec and framework files - -import 'zone.js/dist/zone-testing'; -import { getTestBed } from '@angular/core/testing'; -import { - BrowserDynamicTestingModule, - platformBrowserDynamicTesting -} from '@angular/platform-browser-dynamic/testing'; - -declare const require: any; - -// First, initialize the Angular testing environment. -getTestBed().initTestEnvironment( - BrowserDynamicTestingModule, - platformBrowserDynamicTesting() -); -// Then we find all the tests. -const context = require.context('./', true, /\.spec\.ts$/); -// And load the modules. -context.keys().map(context); diff --git a/src/types/tauri.d.ts b/src/types/tauri.d.ts new file mode 100644 index 0000000..b9104be --- /dev/null +++ b/src/types/tauri.d.ts @@ -0,0 +1,3 @@ +declare module '@tauri-apps/api/dialog'; +declare module '@tauri-apps/api/fs'; +declare module '@tauri-apps/api/shell'; diff --git a/src/typings.d.ts b/src/typings.d.ts index 8e3a6f7..8541926 100644 --- a/src/typings.d.ts +++ b/src/typings.d.ts @@ -2,6 +2,7 @@ declare var require: any; declare module 'awesome-phonenumber'; +declare module 'vcf'; declare var module: NodeModule; interface NodeModule { id: string; diff --git a/src/vitest.setup.ts b/src/vitest.setup.ts new file mode 100644 index 0000000..a860f6a --- /dev/null +++ b/src/vitest.setup.ts @@ -0,0 +1,10 @@ +import { getTestBed } from '@angular/core/testing'; +import { + BrowserTestingModule, + platformBrowserTesting, +} from '@angular/platform-browser/testing'; + +getTestBed().initTestEnvironment( + BrowserTestingModule, + platformBrowserTesting() +); diff --git a/tools/join-backups/README.md b/tools/join-backups/README.md new file mode 100644 index 0000000..4593d71 --- /dev/null +++ b/tools/join-backups/README.md @@ -0,0 +1,42 @@ +join-backups +=============== + +Simple CLI to join multiple SMS Backup XML files into one merged backup. + +Install +------- + +cd tools/join-backups +npm install + +Usage +----- + +CLI: +# merge a few backups into merged.xml +node index.js merged.xml backup1.xml backup2.xml backup3.xml + +Or install globally and use `join-backups` if you prefer: + +npm install -g . +join-backups merged.xml backup1.xml backup2.xml + +GUI: +Open `tools/join-backups/gui/index.html` in your browser (or serve it with a static server: `npx http-server tools/join-backups/gui -p 8081`) and choose files in the UI to merge and download the combined XML. + +Tauri desktop app: +1. Install prerequisites: Rust toolchain (rustup), and the usual Tauri build requirements for your platform. +2. From the `tools/join-backups` folder install dev deps: `npm install` (this will install `@tauri-apps/cli`). +3. Run the GUI dev server and Tauri dev together with the convenience script: + - `npm run tauri:dev` (this will run the configured `beforeDevCommand` to serve the GUI at http://localhost:8081 and open a Tauri window) +4. Build a distributable with `npm run tauri:build`. + +Notes: +- The Tauri app is configured to serve the files from `tools/join-backups/gui` in production and will use `http://localhost:8081` during `tauri dev`. + +Notes +----- +- The tool looks for the top-level root (commonly `smses`) and merges the `` entries. +- It preserves/combines attributes found on the first file and sets `count` to the actual message count. +- The GUI runs entirely in the browser; files are not uploaded anywhere. +- This is a minimal tool; validate the resulting XML with your usual workflow. diff --git a/tools/join-backups/gui/app.js b/tools/join-backups/gui/app.js new file mode 100644 index 0000000..f3a4734 --- /dev/null +++ b/tools/join-backups/gui/app.js @@ -0,0 +1,147 @@ +(function () { + const filesEl = document.getElementById('files'); + const fileListEl = document.getElementById('fileList'); + const mergeBtn = document.getElementById('mergeBtn'); + const statusEl = document.getElementById('status'); + const outName = document.getElementById('outname'); + const downloadLink = document.getElementById('downloadLink'); + + let selectedFiles = []; + + filesEl.addEventListener('change', (e) => { + selectedFiles = Array.from(filesEl.files || []); + renderFileList(); + }); + + // Drag & drop support + const dropZone = document.getElementById('dropZone'); + dropZone.addEventListener('dragover', (e) => { e.preventDefault(); dropZone.style.borderColor = '#2563eb'; }); + dropZone.addEventListener('dragleave', (e) => { e.preventDefault(); dropZone.style.borderColor = '#ccc'; }); + dropZone.addEventListener('drop', (e) => { + e.preventDefault(); + dropZone.style.borderColor = '#ccc'; + const dt = e.dataTransfer; + if (dt && dt.files && dt.files.length) { + selectedFiles = Array.from(dt.files).filter(f => f.name && f.name.toLowerCase().endsWith('.xml')); + filesEl.files = dt.files; // optional + renderFileList(); + } + }); + + function renderFileList() { + if (!selectedFiles.length) { + fileListEl.textContent = 'No files selected'; + } else { + fileListEl.innerHTML = selectedFiles.map((f, idx) => `${idx+1}. ${escapeHtml(f.name)} (${f.size} bytes)`).join('
'); + } + downloadLink.style.display = 'none'; + statusEl.textContent = ''; + document.getElementById('preview').style.display = 'none'; + } + + mergeBtn.addEventListener('click', async () => { + if (!selectedFiles.length) { + statusEl.textContent = 'Please choose at least one XML backup to merge.'; + return; + } + statusEl.textContent = 'Reading files...'; + downloadLink.style.display = 'none'; + + try { + const reads = selectedFiles.map(f => readFileAsText(f)); + const contents = await Promise.all(reads); + + const parser = new window['fastXmlParser'].XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' }); + const builder = new window['fastXmlParser'].XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@_', format: true }); + + let merged = []; + let topName = null; + let topAttrs = {}; + + // For preview, collect some metadata + let totalMsgs = 0; + const contactSet = new Set(); + + for (const c of contents) { + // quick validation: try parsing + let parsed; + try { + parsed = parser.parse(c); + } catch (err) { + statusEl.textContent = 'One of the files is not valid XML or not a supported SMS backup.'; + console.error('Invalid XML parse', err); + return; + } + + const keys = Object.keys(parsed); + if (!keys.length) continue; + const rootName = keys[0]; + const root = parsed[rootName]; + + if (!topName) { + topName = rootName; + // collect '@_' attributes from root + for (const k of Object.keys(root || {})) { + if (k.startsWith('@_')) topAttrs[k] = root[k]; + } + } + + const smsNodes = root && root.sms ? root.sms : []; + const nodes = Array.isArray(smsNodes) ? smsNodes : (smsNodes && typeof smsNodes === 'object' ? [smsNodes] : []); + merged = merged.concat(nodes); + + // collect preview info + totalMsgs += nodes.length; + for (const m of nodes) { + const addr = m['@_address'] || m.address || m.contact || ''; + if (addr) contactSet.add(addr); + } + } + + // build root preserving attributes and setting count + const outRoot = Object.assign({}, topAttrs); + outRoot['sms'] = merged; + outRoot['@_count'] = String(merged.length); + + const outObj = {}; + outObj[topName || 'smses'] = outRoot; + + const xml = builder.build(outObj); + + // Update preview + const previewEl = document.getElementById('preview'); + const previewContent = document.getElementById('previewContent'); + previewContent.innerHTML = `Selected files: ${selectedFiles.length}
Estimated messages merged: ${merged.length}
Unique contacts: ${contactSet.size}`; + previewEl.style.display = 'block'; + + // Prepare download link + const blob = new Blob([xml], { type: 'application/xml' }); + const name = (outName.value && outName.value.trim()) ? outName.value.trim() : 'merged.xml'; + + const url = URL.createObjectURL(blob); + downloadLink.href = url; + downloadLink.download = name; + downloadLink.textContent = 'Download ' + name; + downloadLink.style.display = 'inline-block'; + + statusEl.textContent = `Ready. Merged ${merged.length} messages.`; + + } catch (err) { + console.error(err); + statusEl.textContent = 'Error merging files: ' + String(err.message || err); + } + }); + + function readFileAsText(file) { + return new Promise((resolve, reject) => { + const r = new FileReader(); + r.onerror = () => reject(r.error); + r.onload = () => resolve(String(r.result || '')); + r.readAsText(file, 'utf-8'); + }); + } + + function escapeHtml(s) { + return s.replace(/[&<>\"]+/g, c => ({'&':'&','<':'<','>':'>','\"':'"'}[c] || c)); + } +})(); \ No newline at end of file diff --git a/tools/join-backups/gui/index.html b/tools/join-backups/gui/index.html new file mode 100644 index 0000000..2932b58 --- /dev/null +++ b/tools/join-backups/gui/index.html @@ -0,0 +1,47 @@ + + + + + + Join Backups (GUI) + + + +
+

Join SMS Backup XML files

+
+
Drop XML files here or
+ + + + +
+ +
No files selected
+ +
+ + + +
+ +

This tool merges the top-level <smses> <sms> entries from multiple SMS Backup XML files into a single file. It runs entirely in your browser (no upload).

+
+ + + + + \ No newline at end of file diff --git a/tools/join-backups/index.js b/tools/join-backups/index.js new file mode 100644 index 0000000..c06bd7d --- /dev/null +++ b/tools/join-backups/index.js @@ -0,0 +1,79 @@ +#!/usr/bin/env node +const fs = require('fs'); +const path = require('path'); +const { XMLParser, XMLBuilder } = require('fast-xml-parser'); + +function usage() { + console.error('Usage: join-backups [in2.xml ...]'); +} + +async function run() { + const args = process.argv.slice(2); + if (args.length < 2) { + usage(); + process.exit(2); + } + + const outPath = args[0]; + const inPaths = args.slice(1); + + const parser = new XMLParser({ ignoreAttributes: false, attributeNamePrefix: '@_' }); + const builder = new XMLBuilder({ ignoreAttributes: false, attributeNamePrefix: '@_', format: true }); + + let mergedSms = []; + let topAttrs = {}; + let topName = null; // e.g., 'smses' + + for (const p of inPaths) { + const content = fs.readFileSync(p, 'utf8'); + const parsed = parser.parse(content); + + // Common backup formats: { smses: { '@_count': '...', sms: [ ... ] } } + // Or some may use mapping. + const rootKeys = Object.keys(parsed); + if (rootKeys.length === 0) continue; + const root = parsed[rootKeys[0]]; + const rootName = rootKeys[0]; + + if (!topName) { + topName = rootName; + // copy attributes if present + if (root && typeof root === 'object') { + Object.keys(root).forEach(k => { + if (k.startsWith('@_')) topAttrs[k] = root[k]; + }); + } + } + + const smsNodes = root && root.sms ? root.sms : []; + + if (Array.isArray(smsNodes)) { + mergedSms = mergedSms.concat(smsNodes); + } else if (smsNodes && typeof smsNodes === 'object') { + mergedSms.push(smsNodes); + } else { + // Nothing under this root - skip + } + } + + // Rebuild root object + // Keep topAttrs (like count), but set count to actual merged length + const mergedRoot = {}; + // attach attributes with prefix used by parser + Object.keys(topAttrs).forEach(k => mergedRoot[k] = topAttrs[k]); + mergedRoot['sms'] = mergedSms; + mergedRoot['@_count'] = String(mergedSms.length); + + const outObj = {}; + outObj[topName || 'smses'] = mergedRoot; + + const xml = builder.build(outObj); + + fs.writeFileSync(outPath, xml, 'utf8'); + console.log(`Wrote ${outPath} (${mergedSms.length} messages)`); +} + +run().catch(err => { + console.error('Error:', err && err.message ? err.message : String(err)); + process.exit(1); +}); diff --git a/tools/join-backups/node_modules/.bin/fxparser b/tools/join-backups/node_modules/.bin/fxparser new file mode 100644 index 0000000..c722e41 --- /dev/null +++ b/tools/join-backups/node_modules/.bin/fxparser @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../fast-xml-parser/src/cli/cli.js" "$@" +else + exec node "$basedir/../fast-xml-parser/src/cli/cli.js" "$@" +fi diff --git a/tools/join-backups/node_modules/.bin/fxparser.cmd b/tools/join-backups/node_modules/.bin/fxparser.cmd new file mode 100644 index 0000000..043b763 --- /dev/null +++ b/tools/join-backups/node_modules/.bin/fxparser.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\fast-xml-parser\src\cli\cli.js" %* diff --git a/tools/join-backups/node_modules/.bin/fxparser.ps1 b/tools/join-backups/node_modules/.bin/fxparser.ps1 new file mode 100644 index 0000000..3e7252a --- /dev/null +++ b/tools/join-backups/node_modules/.bin/fxparser.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../fast-xml-parser/src/cli/cli.js" $args + } else { + & "$basedir/node$exe" "$basedir/../fast-xml-parser/src/cli/cli.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../fast-xml-parser/src/cli/cli.js" $args + } else { + & "node$exe" "$basedir/../fast-xml-parser/src/cli/cli.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/tools/join-backups/node_modules/.bin/tauri b/tools/join-backups/node_modules/.bin/tauri new file mode 100644 index 0000000..546529b --- /dev/null +++ b/tools/join-backups/node_modules/.bin/tauri @@ -0,0 +1,16 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*|*MINGW*|*MSYS*) + if command -v cygpath > /dev/null 2>&1; then + basedir=`cygpath -w "$basedir"` + fi + ;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@tauri-apps/cli/tauri.js" "$@" +else + exec node "$basedir/../@tauri-apps/cli/tauri.js" "$@" +fi diff --git a/tools/join-backups/node_modules/.bin/tauri.cmd b/tools/join-backups/node_modules/.bin/tauri.cmd new file mode 100644 index 0000000..534b08c --- /dev/null +++ b/tools/join-backups/node_modules/.bin/tauri.cmd @@ -0,0 +1,17 @@ +@ECHO off +GOTO start +:find_dp0 +SET dp0=%~dp0 +EXIT /b +:start +SETLOCAL +CALL :find_dp0 + +IF EXIST "%dp0%\node.exe" ( + SET "_prog=%dp0%\node.exe" +) ELSE ( + SET "_prog=node" + SET PATHEXT=%PATHEXT:;.JS;=;% +) + +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\@tauri-apps\cli\tauri.js" %* diff --git a/tools/join-backups/node_modules/.bin/tauri.ps1 b/tools/join-backups/node_modules/.bin/tauri.ps1 new file mode 100644 index 0000000..01b0ad7 --- /dev/null +++ b/tools/join-backups/node_modules/.bin/tauri.ps1 @@ -0,0 +1,28 @@ +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" "$basedir/../@tauri-apps/cli/tauri.js" $args + } else { + & "$basedir/node$exe" "$basedir/../@tauri-apps/cli/tauri.js" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" "$basedir/../@tauri-apps/cli/tauri.js" $args + } else { + & "node$exe" "$basedir/../@tauri-apps/cli/tauri.js" $args + } + $ret=$LASTEXITCODE +} +exit $ret diff --git a/tools/join-backups/node_modules/.package-lock.json b/tools/join-backups/node_modules/.package-lock.json new file mode 100644 index 0000000..8c4bb4e --- /dev/null +++ b/tools/join-backups/node_modules/.package-lock.json @@ -0,0 +1,85 @@ +{ + "name": "join-backups", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "node_modules/@tauri-apps/cli": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.6.tgz", + "integrity": "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.9.6", + "@tauri-apps/cli-darwin-x64": "2.9.6", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", + "@tauri-apps/cli-linux-arm64-musl": "2.9.6", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-musl": "2.9.6", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", + "@tauri-apps/cli-win32-x64-msvc": "2.9.6" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.6.tgz", + "integrity": "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + } + } +} diff --git a/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/README.md b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/README.md new file mode 100644 index 0000000..c22490b --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/README.md @@ -0,0 +1,3 @@ +# `@tauri-apps/cli-win32-x64-msvc` + +This is the **x86_64-pc-windows-msvc** binary for `@tauri-apps/cli` diff --git a/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/cli.win32-x64-msvc.node b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/cli.win32-x64-msvc.node new file mode 100644 index 0000000..19fc7d1 Binary files /dev/null and b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/cli.win32-x64-msvc.node differ diff --git a/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/package.json b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/package.json new file mode 100644 index 0000000..60025ff --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli-win32-x64-msvc/package.json @@ -0,0 +1,33 @@ +{ + "name": "@tauri-apps/cli-win32-x64-msvc", + "version": "2.9.6", + "cpu": [ + "x64" + ], + "main": "cli.win32-x64-msvc.node", + "files": [ + "cli.win32-x64-msvc.node" + ], + "description": "Command line interface for building Tauri apps", + "homepage": "https://github.com/tauri-apps/tauri#readme", + "contributors": [ + "Tauri Programme within The Commons Conservancy" + ], + "license": "Apache-2.0 OR MIT", + "engines": { + "node": ">= 10" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tauri-apps/tauri.git" + }, + "bugs": { + "url": "https://github.com/tauri-apps/tauri/issues" + }, + "publishConfig": { + "access": "public" + }, + "os": [ + "win32" + ] +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/CHANGELOG.md b/tools/join-backups/node_modules/@tauri-apps/cli/CHANGELOG.md new file mode 100644 index 0000000..305a65a --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/CHANGELOG.md @@ -0,0 +1,1977 @@ +# Changelog + +## \[2.9.6] + +### Dependencies + +- Upgraded to `tauri-cli@2.9.6` + +## \[2.9.5] + +### Bug Fixes + +- [`f855caf8a`](https://www.github.com/tauri-apps/tauri/commit/f855caf8a3830aa5dd6d0b039312866a5d9c3606) ([#14481](https://www.github.com/tauri-apps/tauri/pull/14481) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fixed the mismatched tauri package versions check didn't work for pnpm + +### Performance Improvements + +- [`ce98d87ce`](https://www.github.com/tauri-apps/tauri/commit/ce98d87ce0aaa907285852eb80691197424e03c3) ([#14474](https://www.github.com/tauri-apps/tauri/pull/14474) by [@Tunglies](https://www.github.com/tauri-apps/tauri/../../Tunglies)) refactor: remove needless collect. No user facing changes. + +### Dependencies + +- Upgraded to `tauri-cli@2.9.5` + +## \[2.9.4] + +### Bug Fixes + +- [`b586ecf1f`](https://www.github.com/tauri-apps/tauri/commit/b586ecf1f4b3b087f9aa6c4668c2c18b1b7925f4) ([#14416](https://www.github.com/tauri-apps/tauri/pull/14416) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Premultiply Alpha before Resizing which gets rid of the gray fringe around the icons for svg images. + +### Dependencies + +- Upgraded to `tauri-cli@2.9.4` + +## \[2.9.3] + +### Bug Fixes + +- [`fd8c30b4f`](https://www.github.com/tauri-apps/tauri/commit/fd8c30b4f1bca8dd7165c5c0ebe7fbfd17662153) ([#14353](https://www.github.com/tauri-apps/tauri/pull/14353) by [@ChaseKnowlden](https://www.github.com/tauri-apps/tauri/../../ChaseKnowlden)) Premultiply Alpha before Resizing which gets rid of the gray fringe around the icons. + +### Dependencies + +- Upgraded to `tauri-cli@2.9.3` + +## \[2.9.2] + +### Dependencies + +- Upgraded to `tauri-cli@2.9.2` + +## \[2.9.1] + +### Dependencies + +- Upgraded to `tauri-cli@2.9.1` + +## \[2.9.0] + +### New Features + +- [`3b4fac201`](https://www.github.com/tauri-apps/tauri/commit/3b4fac2017832d426dd07c5e24e26684eda57f7b) ([#14194](https://www.github.com/tauri-apps/tauri/pull/14194)) Add `tauri.conf.json > bundle > android > autoIncrementVersionCode` config option to automatically increment the Android version code. +- [`673867aa0`](https://www.github.com/tauri-apps/tauri/commit/673867aa0e1ccd766ee879ffe96aba58c758613c) ([#14094](https://www.github.com/tauri-apps/tauri/pull/14094)) Try to detect ANDROID_HOME and NDK_HOME environment variables from default system locations and install them if needed using the Android Studio command line tools. +- [`3d6868d09`](https://www.github.com/tauri-apps/tauri/commit/3d6868d09c323d68a152f3c3f8c7256311bd020a) ([#14128](https://www.github.com/tauri-apps/tauri/pull/14128)) Added support to defining the content type of the declared file association on macOS (maps to LSItemContentTypes property). +- [`3d6868d09`](https://www.github.com/tauri-apps/tauri/commit/3d6868d09c323d68a152f3c3f8c7256311bd020a) ([#14128](https://www.github.com/tauri-apps/tauri/pull/14128)) Added support to defining the metadata for custom types declared in `tauri.conf.json > bundle > fileAssociations > exportedType` via the `UTExportedTypeDeclarations` Info.plist property. +- [`ed7c9a410`](https://www.github.com/tauri-apps/tauri/commit/ed7c9a4100e08c002212265549d12130d021ad1e) ([#14108](https://www.github.com/tauri-apps/tauri/pull/14108)) Added `bundle > macOS > infoPlist` and `bundle > iOS > infoPlist` configurations to allow defining custom Info.plist extensions. +- [`75082cc5b`](https://www.github.com/tauri-apps/tauri/commit/75082cc5b340e30e2c4b4cd4bd6a1fe5382164aa) ([#14120](https://www.github.com/tauri-apps/tauri/pull/14120)) Added `ios run` and `android run` commands to run the app in production mode. +- [`cc8c0b531`](https://www.github.com/tauri-apps/tauri/commit/cc8c0b53171173dbd1d01781a50de1a3ea159031) ([#14031](https://www.github.com/tauri-apps/tauri/pull/14031)) Added support to universal app links on macOS with the `plugins > deep-link > desktop > domains` configuration. + +### Enhancements + +- [`b5aa01870`](https://www.github.com/tauri-apps/tauri/commit/b5aa018702bf45dc98297698f9b7d238705865a6) ([#14268](https://www.github.com/tauri-apps/tauri/pull/14268)) Update cargo-mobile2 to 0.21, enhancing error messages and opening Xcode when multiple apps are installed. +- [`55453e845`](https://www.github.com/tauri-apps/tauri/commit/55453e8453d927b8197f1ba9f26fd944482938f7) ([#14262](https://www.github.com/tauri-apps/tauri/pull/14262)) Check mismatched versions in `tauri info` +- [`1a6627ee7`](https://www.github.com/tauri-apps/tauri/commit/1a6627ee7d085a4e66784e2705254714d68c7244) ([#14122](https://www.github.com/tauri-apps/tauri/pull/14122)) Set a default log level filter when running `tauri add log`. +- [`b06b3bd09`](https://www.github.com/tauri-apps/tauri/commit/b06b3bd091b0fed26cdcfb23cacb0462a7a9cc2d) ([#14126](https://www.github.com/tauri-apps/tauri/pull/14126)) Improve error messages with more context. +- [`f6622a3e3`](https://www.github.com/tauri-apps/tauri/commit/f6622a3e342f5dd5fb3cf6e0f79fb309a10e9b3d) ([#14129](https://www.github.com/tauri-apps/tauri/pull/14129)) Prompt to install the iOS platform if it isn't installed yet. +- [`6bbb530fd`](https://www.github.com/tauri-apps/tauri/commit/6bbb530fd5edfc07b180a4f3782b8566872ca3b1) ([#14105](https://www.github.com/tauri-apps/tauri/pull/14105)) Warn if productName is empty when initializing mobile project. + +### Bug Fixes + +- [`19fb6f7cb`](https://www.github.com/tauri-apps/tauri/commit/19fb6f7cb0d702cb2f25f6f2d1e11014d9dada5d) ([#14146](https://www.github.com/tauri-apps/tauri/pull/14146)) Strip Windows-only extensions from the binary path so an Android project initialized on Windows can be used on UNIX systems. +- [`19fb6f7cb`](https://www.github.com/tauri-apps/tauri/commit/19fb6f7cb0d702cb2f25f6f2d1e11014d9dada5d) ([#14146](https://www.github.com/tauri-apps/tauri/pull/14146)) Enhance Android build script usage on Windows by attempting to run cmd, bat and exe formats. +- [`28a2f9bc5`](https://www.github.com/tauri-apps/tauri/commit/28a2f9bc55f658eb71ef1a970ff9f791346f7682) ([#14101](https://www.github.com/tauri-apps/tauri/pull/14101)) Fix iOS CLI usage after modifying the package name. +- [`d2938486e`](https://www.github.com/tauri-apps/tauri/commit/d2938486e9d974debd90c15d7160b8a17bf4d763) ([#14261](https://www.github.com/tauri-apps/tauri/pull/14261)) Replaced the non-standard nerd font character with ` ⱼₛ ` in `tarui info` +- [`25e920e16`](https://www.github.com/tauri-apps/tauri/commit/25e920e169db900ca4f07c2bb9eb290e9f9f2c7d) ([#14298](https://www.github.com/tauri-apps/tauri/pull/14298)) Wait for dev server to exit before exiting the CLI when the app is closed on `tauri dev --no-watch`. +- [`b0012424c`](https://www.github.com/tauri-apps/tauri/commit/b0012424c5f432debfa42ba145e2672966d5f6d5) ([#14115](https://www.github.com/tauri-apps/tauri/pull/14115)) Resolve local IP address when `tauri.conf.json > build > devUrl` host is `0.0.0.0`. +- [`abf7e8850`](https://www.github.com/tauri-apps/tauri/commit/abf7e8850ba41e7173e9e9a3fdd6dfb8f357d72d) ([#14118](https://www.github.com/tauri-apps/tauri/pull/14118)) Fixes mobile project initialization when using `pnpx` or `pnpm dlx`. + +### Dependencies + +- Upgraded to `tauri-cli@2.9.0` + +## \[2.8.4] + +### Enhancements + +- [`f70b28529`](https://www.github.com/tauri-apps/tauri/commit/f70b28529d226a2dec2f41709d8934f8f5adab25) ([#14093](https://www.github.com/tauri-apps/tauri/pull/14093) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ensure Rust targets for mobile are installed when running the dev and build commands (previously only checked on init). +- [`a9b342125`](https://www.github.com/tauri-apps/tauri/commit/a9b342125d5ac1bc9a4b2e8b5f73e8ca3cbcb8b2) ([#14114](https://www.github.com/tauri-apps/tauri/pull/14114) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS dev and build targeting the simulator on Intel machines. +- [`61b9b681e`](https://www.github.com/tauri-apps/tauri/commit/61b9b681e88067a53b79d2318ae005dc25addcd6) ([#14111](https://www.github.com/tauri-apps/tauri/pull/14111) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Retain `RUST_*` environment variables when running the mobile commands. +- [`c23bec62d`](https://www.github.com/tauri-apps/tauri/commit/c23bec62d6d5724798869681aa1534423aae28e2) ([#14083](https://www.github.com/tauri-apps/tauri/pull/14083) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Tauri now ignores `macOS.minimumSystemVersion` in `tauri dev` to prevent forced rebuilds of macOS specific dependencies when using something like `rust-analyzer` at the same time as `tauri dev`. + +### Bug Fixes + +- [`c37a29833`](https://www.github.com/tauri-apps/tauri/commit/c37a298331d6d744b15d32d55a2db83c884a3d6a) ([#14112](https://www.github.com/tauri-apps/tauri/pull/14112) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix usage with Deno failing with `ReferenceError: require is not defined`. +- [`bcf000c0a`](https://www.github.com/tauri-apps/tauri/commit/bcf000c0a8607eedf488fb949b982f519abda43d) ([#14110](https://www.github.com/tauri-apps/tauri/pull/14110) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `ios` commands with `deno` crashing due to incorrect current working directory resolution. +- [`7db7142f9`](https://www.github.com/tauri-apps/tauri/commit/7db7142f9ff7dc2f5719602e199b77129ceb19d3) ([#14119](https://www.github.com/tauri-apps/tauri/pull/14119) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes empty device name when using an Android emulator causing the emulator to never be detected as running. +- [`956b4fd6f`](https://www.github.com/tauri-apps/tauri/commit/956b4fd6ffbb4312123b107ca96c87a001359b9d) ([#14106](https://www.github.com/tauri-apps/tauri/pull/14106) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the correct export method on Xcode < 15.4. + +### Dependencies + +- Upgraded to `tauri-cli@2.8.4` + +## \[2.8.3] + +### Bug Fixes + +- [`0ac89d3b6`](https://www.github.com/tauri-apps/tauri/commit/0ac89d3b6c8c4a4826a4c42726e4f4a8941b3fde) ([#14078](https://www.github.com/tauri-apps/tauri/pull/14078) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Updated `cargo-mobile2` to allow running on iOS simulators that have a higher version than the XCode SDK. This fixes compatiblity issues with Apple's recent "iOS 18.5 + iOS 18.6 Simulator" platform support component. + +### Dependencies + +- Upgraded to `tauri-cli@2.8.3` + +## \[2.8.2] + +### Dependencies + +- Upgraded to `tauri-cli@2.8.1` + +## \[2.8.1] + +### Bug Fixes + +- [`f0172a454`](https://www.github.com/tauri-apps/tauri/commit/f0172a454aea101cb699233be3d73dbf86e64a31) ([#14038](https://www.github.com/tauri-apps/tauri/pull/14038) by [@KushalMeghani1644](https://www.github.com/tauri-apps/tauri/../../KushalMeghani1644)) Fixes `removeDataStore` return type. + +## \[2.8.0] + +### New Features + +- [`91508c0b8`](https://www.github.com/tauri-apps/tauri/commit/91508c0b8d16ec61c7706e93b711c5a85aaffb4a) ([#13881](https://www.github.com/tauri-apps/tauri/pull/13881) by [@pepperoni505](https://www.github.com/tauri-apps/tauri/../../pepperoni505)) Introduces a new configuration option that allows you to specify custom folders to watch for changes when running `tauri dev`. +- [`bc4afe7dd`](https://www.github.com/tauri-apps/tauri/commit/bc4afe7dd4780f02c2d4b1f07d97185fbc5d2bba) ([#13993](https://www.github.com/tauri-apps/tauri/pull/13993) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Check installed plugin NPM/crate versions for incompatible releases. +- [`0c402bfb6`](https://www.github.com/tauri-apps/tauri/commit/0c402bfb6bd0bec24d928fcabe2ffef1f5cff19a) ([#13997](https://www.github.com/tauri-apps/tauri/pull/13997) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Increase default iOS deployment target iOS to 14.0. +- [`d6d5f3707`](https://www.github.com/tauri-apps/tauri/commit/d6d5f3707768a094ff7e961ae75ba0398d772655) ([#13358](https://www.github.com/tauri-apps/tauri/pull/13358) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `--root-certificate-path` option to `android dev` and `ios dev` to be able to connect to HTTPS dev servers. + +### Enhancements + +- [`8b465a12b`](https://www.github.com/tauri-apps/tauri/commit/8b465a12ba73e94d7a3995defd9cc362d15eeebe) ([#13913](https://www.github.com/tauri-apps/tauri/pull/13913) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) The bundler now pulls the latest AppImage linuxdeploy plugin instead of using the built-in one. This should remove the libfuse requirement. +- [`390cb9c36`](https://www.github.com/tauri-apps/tauri/commit/390cb9c36a4e2416891b64514e7ad5fc0a85ccf2) ([#13953](https://www.github.com/tauri-apps/tauri/pull/13953) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Reduced the log level of the binary patcher crate `goblin` to only show its debug logs in `-vv` and above. +- [`4475e93e1`](https://www.github.com/tauri-apps/tauri/commit/4475e93e136e9e2bd5f3c7817fa2040924f630f6) ([#13824](https://www.github.com/tauri-apps/tauri/pull/13824) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) The bundler and cli will now read TLS Certificates installed on the system when downloading tools and checking versions. + +### Bug Fixes + +- [`f0dcf9637`](https://www.github.com/tauri-apps/tauri/commit/f0dcf9637cc0d42eda05fed7dd6c5ff98bbf19ae) ([#13980](https://www.github.com/tauri-apps/tauri/pull/13980) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fix the generated plugin init code of `tauri add` for `tauri-plugin-autostart` and `tauri-plugin-single-instance` +- [`4d270a96a`](https://www.github.com/tauri-apps/tauri/commit/4d270a96a891ae83f7df751abcbe12b7072212d5) ([#13943](https://www.github.com/tauri-apps/tauri/pull/13943) by [@acx0](https://www.github.com/tauri-apps/tauri/../../acx0)) Fix codesigning verification failures caused by binary-patching during bundling +- [`b21d86a8a`](https://www.github.com/tauri-apps/tauri/commit/b21d86a8a3ef29f16628b7d4de17ce1214e9bf49) ([#13981](https://www.github.com/tauri-apps/tauri/pull/13981) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fix `tauri permission add` could add duplicated permissions to the capability files +- [`9c938be45`](https://www.github.com/tauri-apps/tauri/commit/9c938be4520fce9204361f3b59439844bc5c91e8) ([#13912](https://www.github.com/tauri-apps/tauri/pull/13912) by [@takecchi](https://www.github.com/tauri-apps/tauri/../../takecchi)) Properly migrate svelte to v5 in the plugin example template + +### Dependencies + +- Upgraded to `tauri-cli@2.8.0` + +## \[2.7.1] + +### Dependencies + +- Upgraded to `tauri-cli@2.7.1` + +## \[2.7.0] + +### New Features + +- [`33d079392`](https://www.github.com/tauri-apps/tauri/commit/33d079392ac4a5a153b7d8a6d82fefd6f54a2bdf) ([#13811](https://www.github.com/tauri-apps/tauri/pull/13811) by [@mhbagheri-99](https://www.github.com/tauri-apps/tauri/../../mhbagheri-99)) Allow runner configuration to be an object with cmd, cwd, and args properties. The runner can now be configured as `{ "cmd": "my_runner", "cwd": "/path", "args": ["--quiet"] }` while maintaining backwards compatibility with the existing string format. + +### Enhancements + +- [`232265c70`](https://www.github.com/tauri-apps/tauri/commit/232265c70e1c213bbb3f84b5541ddc07d330fce1) ([#13209](https://www.github.com/tauri-apps/tauri/pull/13209) by [@kandrelczyk](https://www.github.com/tauri-apps/tauri/../../kandrelczyk)) Binaries are patched before bundling to add the type of a bundle they will placed in. This information will be used during update process to select the correct target. + +### Bug Fixes + +- [`916aeaa48`](https://www.github.com/tauri-apps/tauri/commit/916aeaa48646a483a78e51cfe1633800ee62c37c) ([#13781](https://www.github.com/tauri-apps/tauri/pull/13781) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes Android dev and build commands reading `tauri.ios.conf.json` instead of `tauri.android.conf.json` to merge platform-specific configuration. +- [`0f248b111`](https://www.github.com/tauri-apps/tauri/commit/0f248b111ffb8af934eaf64bd8f4591e628da786) ([#13799](https://www.github.com/tauri-apps/tauri/pull/13799) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Install iOS dependencies when needed. +- [`7a6fd5b75`](https://www.github.com/tauri-apps/tauri/commit/7a6fd5b75d61071e2771f6277c0376ec206d302a) ([#13863](https://www.github.com/tauri-apps/tauri/pull/13863) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) The AppImage bundler now pulls the AppRun binaries from our GitHub mirror, fixing 404 errors. +- [`bda830410`](https://www.github.com/tauri-apps/tauri/commit/bda8304107da7ca60caaba5674faa793491898c6) ([#13833](https://www.github.com/tauri-apps/tauri/pull/13833) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fail with an error when trying to migrate from v2 alpha +- [`bda830410`](https://www.github.com/tauri-apps/tauri/commit/bda8304107da7ca60caaba5674faa793491898c6) ([#13833](https://www.github.com/tauri-apps/tauri/pull/13833) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Use v2 stable instead of v2-rc when migrating from v2-beta + +### Dependencies + +- Upgraded to `tauri-cli@2.7.0` + +## \[2.6.2] + +### Bug Fixes + +- [`cbd962972`](https://www.github.com/tauri-apps/tauri/commit/cbd9629729ed6eb208ba2234d014c11c4e9f1c8c) ([#13730](https://www.github.com/tauri-apps/tauri/pull/13730) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Load `--config` arguments when running the Xcode and Android Studio build scripts. + +### Dependencies + +- Upgraded to `tauri-cli@2.6.2` + +## \[2.6.1] + +### Dependencies + +- Upgraded to `tauri-cli@2.6.1` + +## \[2.6.0] + +### New Features + +- [`414619c36`](https://www.github.com/tauri-apps/tauri/commit/414619c36e94e21939534dd72c0438b93da75546) ([#13536](https://www.github.com/tauri-apps/tauri/pull/13536) by [@Tunglies](https://www.github.com/tauri-apps/tauri/../../Tunglies)) Added support for the `bundleName` property in the macOS bundler configuration. This allows specifying the `CFBundleName` value for generated macOS bundles. +- [`3242e1c94`](https://www.github.com/tauri-apps/tauri/commit/3242e1c946c441b58665ba5d612f3a3f1eafe0b6) ([#13659](https://www.github.com/tauri-apps/tauri/pull/13659) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Allow passing Cargo arguments to mobile dev and build commands. +- [`d1ce9af62`](https://www.github.com/tauri-apps/tauri/commit/d1ce9af62881e3f7d86a495c9c40df5b7f9d1c04) ([#13660](https://www.github.com/tauri-apps/tauri/pull/13660) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Allow passing `--config` arguments to the `ios init` and `android init` commands to tweak the configuration used to initialize the mobile projects. +- [`7322f0579`](https://www.github.com/tauri-apps/tauri/commit/7322f057923aaec88960ad5556776774b745762f) ([#13502](https://www.github.com/tauri-apps/tauri/pull/13502) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Allow using `CheckIfAppIsRunning` macro inside NSIS hooks, for example `!insertmacro CheckIfAppIsRunning "another-executable.exe" "Another Executable"`. +- [`4a880ca69`](https://www.github.com/tauri-apps/tauri/commit/4a880ca697bab6d63a2a51ea94e1988cc8c4ea4a) ([#13658](https://www.github.com/tauri-apps/tauri/pull/13658) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Synchronize Tauri config productName changes with the iOS Xcode project. +- [`8ee14a864`](https://www.github.com/tauri-apps/tauri/commit/8ee14a86480510c15823586cf28084e615cb7a9c) ([#13618](https://www.github.com/tauri-apps/tauri/pull/13618) by [@Sky-walkerX](https://www.github.com/tauri-apps/tauri/../../Sky-walkerX)) Warn the user that the app id shouldn't end in `.app` because it conflicts with the application bundle extension on macOS + +### Bug Fixes + +- [`35aa7e121`](https://www.github.com/tauri-apps/tauri/commit/35aa7e1218f34d0805e280e3ec32529d0cb0d733) ([#13294](https://www.github.com/tauri-apps/tauri/pull/13294) by [@kingsword09](https://www.github.com/tauri-apps/tauri/../../kingsword09)) fix: allow the target directory to be inside frontendDir as long as it is not the Rust target directory inside frontendDir. +- [`ec6065fa4`](https://www.github.com/tauri-apps/tauri/commit/ec6065fa4a6427266ecfb0c0f62f008574bb7880) ([#13625](https://www.github.com/tauri-apps/tauri/pull/13625) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes Android and iOS dev/build commands not working when the app identifier is being modified by the `--config` option. +- [`5a5291d66`](https://www.github.com/tauri-apps/tauri/commit/5a5291d66cb8a955c9d4f8e975782646ac0cc6e7) ([#13483](https://www.github.com/tauri-apps/tauri/pull/13483) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix simulator build detection on Xcode. + +### Dependencies + +- Upgraded to `tauri-cli@2.6.0` +- [`9c16eefa3`](https://www.github.com/tauri-apps/tauri/commit/9c16eefa319b4697bac1d1019bbb5f93eca63173) ([#13629](https://www.github.com/tauri-apps/tauri/pull/13629) by [@sftse](https://www.github.com/tauri-apps/tauri/../../sftse)) Update html5ever to 0.29 and kuchikiki to version 0.8.8-speedreader. + +## \[2.5.0] + +### New Features + +- [`0aa48fb9e`](https://www.github.com/tauri-apps/tauri/commit/0aa48fb9e4b9d7b5bf3522000a76ebc1836394ed) ([#13030](https://www.github.com/tauri-apps/tauri/pull/13030)) Added `bundleVersion` to iOS and macOS configuration to support specifying a `CFBundleVersion`. + +### Enhancements + +- [`ad3fd3890`](https://www.github.com/tauri-apps/tauri/commit/ad3fd3890f1fa26a9f9be04ff1bc156d6dd2a8bc) ([#13152](https://www.github.com/tauri-apps/tauri/pull/13152)) Detect package manager from environment variable `npm_config_user_agent` first +- [`82406c61e`](https://www.github.com/tauri-apps/tauri/commit/82406c61e0fbb775ef00791ccab45349325bdd45) ([#13231](https://www.github.com/tauri-apps/tauri/pull/13231)) Improve iOS simulator usage, checking if Xcode iOS SDK is installed and allowing usage of Simulator for older iOS releases (previously only supported when running on Xcode via `ios dev --open`). + +### Bug Fixes + +- [`2dccfab53`](https://www.github.com/tauri-apps/tauri/commit/2dccfab5321fef55d45f3a4c674b6151b1c4424a) ([#13236](https://www.github.com/tauri-apps/tauri/pull/13236)) Fix `fileAssociations` missing `LSHandlerRank` on macOS. +- [`080252903`](https://www.github.com/tauri-apps/tauri/commit/0802529031c4fd309edff374a8694e93ddec161d) ([#13210](https://www.github.com/tauri-apps/tauri/pull/13210)) Fixes iOS dev not working on Xcode 16.3 simulators. To apply the fix, either regenerate the Xcode project with `rm -r src-tauri/gen/apple && tauri ios init` or remove the `arm64-sim` architecture from the Xcode project. + +### Dependencies + +- Upgraded to `tauri-cli@2.5.0` + +## \[2.4.1] + +### Enhancements + +- [`f805061d1`](https://www.github.com/tauri-apps/tauri/commit/f805061d1152bc4790dbdb9475a506afcdd1de75) ([#13079](https://www.github.com/tauri-apps/tauri/pull/13079) by [@Pietagorh](https://www.github.com/tauri-apps/tauri/../../Pietagorh)) Add support for passing TOML and JSON5 config files to `--config` arg + +### Bug Fixes + +- [`794af778e`](https://www.github.com/tauri-apps/tauri/commit/794af778e4915ffb6a4fe9bae8fba04bc880503d) ([#13117](https://www.github.com/tauri-apps/tauri/pull/13117) by [@Legend-Master](https://www.github.com/tauri-apps/tauri/../../Legend-Master)) Fix setting merge config value to null with `--config` arg no longer works + +### Dependencies + +- Upgraded to `tauri-cli@2.4.1` + +## \[2.4.0] + +### New Features + +- [`d91bfa5cb`](https://www.github.com/tauri-apps/tauri/commit/d91bfa5cb921a078758edd45ef3eaff71358d1eb) ([#12970](https://www.github.com/tauri-apps/tauri/pull/12970) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Allow merging multiple configuration values on `tauri dev`, `tauri build`, `tauri bundle`, `tauri android dev`, `tauri android build`, `tauri ios dev` and `tauri ios build`. +- [`30f5a1553`](https://www.github.com/tauri-apps/tauri/commit/30f5a1553d3c0ce460c9006764200a9210915a44) ([#12366](https://www.github.com/tauri-apps/tauri/pull/12366) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Added `trafficLightPosition` window configuration to set the traffic light buttons position on macOS. + +### Enhancements + +- [`f981a5ee8`](https://www.github.com/tauri-apps/tauri/commit/f981a5ee8b292b9ea09329f60cecc7f688dda734) ([#12602](https://www.github.com/tauri-apps/tauri/pull/12602) by [@kxxt](https://www.github.com/tauri-apps/tauri/../../kxxt)) Add basic support for linux riscv64 platform. + +### Bug Fixes + +- [`0c4700e99`](https://www.github.com/tauri-apps/tauri/commit/0c4700e9907f242eabe579eb6149a1d75174185c) ([#12985](https://www.github.com/tauri-apps/tauri/pull/12985) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) The cli will now accept `--bundles updater` again. It's still no-op as it has been for all v2 versions. If you want to build updater artifacts, enable `createUpdaterArtifacts` in `tauri.conf.json`. +- [`b83921226`](https://www.github.com/tauri-apps/tauri/commit/b83921226cb3084992bb5357e7e39a09ea97843e) ([#12977](https://www.github.com/tauri-apps/tauri/pull/12977) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix `tauri ios` commands using the wrong working directory with `bun@>1.2`. +- [`f268b3dbd`](https://www.github.com/tauri-apps/tauri/commit/f268b3dbdf313484c85b4a1f69cd7cec63049f35) ([#12871](https://www.github.com/tauri-apps/tauri/pull/12871) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ignore parent .gitignore files on the Tauri project path detection. + +### Dependencies + +- Upgraded to `tauri-cli@2.4.0` + +## \[2.3.1] + +### Dependencies + +- Upgraded to `tauri-cli@2.3.1` + +## \[2.3.0] + +### Enhancements + +- [`a2d36b8c3`](https://www.github.com/tauri-apps/tauri/commit/a2d36b8c34a8dcfc6736797ca5cd4665faf75e7e) ([#12181](https://www.github.com/tauri-apps/tauri/pull/12181) by [@bastiankistner](https://www.github.com/tauri-apps/tauri/../../bastiankistner)) Add an option to change the default background throttling policy (currently for WebKit only). + +### Dependencies + +- Upgraded to `tauri-cli@2.3.0` + +## \[2.2.7] + +### Bug Fixes + +- [`8e9134c4a`](https://www.github.com/tauri-apps/tauri/commit/8e9134c4a2047329be0dbb868b7ae061a9d3f190) ([#12511](https://www.github.com/tauri-apps/tauri/pull/12511) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused `tauri dev` to fail because of an incorrect `--bins` flag. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.7` + +## \[2.2.6] + +### Enhancements + +- [`1a86974aa`](https://www.github.com/tauri-apps/tauri/commit/1a86974aa3d09957c6b1142a17bbfed9998798fd) ([#12406](https://www.github.com/tauri-apps/tauri/pull/12406) by [@bradleat](https://www.github.com/tauri-apps/tauri/../../bradleat)) `ios build --open` will now let xcode start the rust build process. +- [`0b79af711`](https://www.github.com/tauri-apps/tauri/commit/0b79af711430934362602fb950c3e4cb5b59cf9c) ([#12438](https://www.github.com/tauri-apps/tauri/pull/12438) by [@3lpsy](https://www.github.com/tauri-apps/tauri/../../3lpsy)) Log the command used to start the rust app in development. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.6` + +## \[2.2.5] + +### Dependencies + +- Upgraded to `tauri-cli@2.2.5` + +## \[2.2.4] + +### Bug Fixes + +- [`cad550445`](https://www.github.com/tauri-apps/tauri/commit/cad5504455ffa53e297cebff473c113b1afa5d29) ([#12354](https://www.github.com/tauri-apps/tauri/pull/12354) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed and issue that caused `tauri add` to try to install incorrect npm packages. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.4` + +## \[2.2.3] + +### Enhancements + +- [`a0f2c84d5`](https://www.github.com/tauri-apps/tauri/commit/a0f2c84d51f5086c5055867d6f61ea90c463a26c) ([#12204](https://www.github.com/tauri-apps/tauri/pull/12204) by [@pjf-dev](https://www.github.com/tauri-apps/tauri/../../pjf-dev)) Enhance `tauri icon` command by including 64x64 png size in default icon sizes. + +### Bug Fixes + +- [`98f62e65a`](https://www.github.com/tauri-apps/tauri/commit/98f62e65a27a375272c6b4d9f34c23e142b9d3a6) ([#12246](https://www.github.com/tauri-apps/tauri/pull/12246) by [@marcomq](https://www.github.com/tauri-apps/tauri/../../marcomq)) Properly add NPM packages for community plugins when using the `tauri add` command. +- [`b9a99a5c6`](https://www.github.com/tauri-apps/tauri/commit/b9a99a5c69d8a2a1a3ff30e500b46872258dca15) ([#12297](https://www.github.com/tauri-apps/tauri/pull/12297) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused the built-in dev server to constantly refresh on Linux. This only affected users who do not have `devUrl` point to a URL. +- [`ef21ed9ac`](https://www.github.com/tauri-apps/tauri/commit/ef21ed9ac1c045c38b0c04e3d71a441694abc257) ([#12290](https://www.github.com/tauri-apps/tauri/pull/12290) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS build failing when the development team contains spaces. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.3` + +## \[2.2.2] + +### Bug Fixes + +- [`26fc9558f`](https://www.github.com/tauri-apps/tauri/commit/26fc9558fe7b2fe649f61926da88f36110dd5707) ([#12178](https://www.github.com/tauri-apps/tauri/pull/12178) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused the `tauri dev` file watcher to exit after detecting file changes. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.2` + +## \[2.2.1] + +### Bug Fixes + +- [`881729448`](https://www.github.com/tauri-apps/tauri/commit/881729448c9abd0d0c7941a8a31c94119ce827af) ([#12164](https://www.github.com/tauri-apps/tauri/pull/12164) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue that caused `tauri dev` to crash before showing the app on Linux. + +### Dependencies + +- Upgraded to `tauri-cli@2.2.1` + +## \[2.2.0] + +### New Features + +- [`cccb308c7`](https://www.github.com/tauri-apps/tauri/commit/cccb308c7b559b0838138d6cea280665f060c925) ([#11562](https://www.github.com/tauri-apps/tauri/pull/11562) by [@jLynx](https://www.github.com/tauri-apps/tauri/../../jLynx)) Generate signature for `.deb` packages when `createUpdaterArtifacts` option is enabled. +- [`74212d40d`](https://www.github.com/tauri-apps/tauri/commit/74212d40d80dba4501b3d4ae30104fa3d447bdf9) ([#11653](https://www.github.com/tauri-apps/tauri/pull/11653) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Include Linux destkop environment and session type in `tauri info` command. + +### Enhancements + +- [`93a3a043d`](https://www.github.com/tauri-apps/tauri/commit/93a3a043d39cc96515d51d98beeb14261d3a246b) ([#11727](https://www.github.com/tauri-apps/tauri/pull/11727) by [@Kiyozz](https://www.github.com/tauri-apps/tauri/../../Kiyozz)) Add support for `Portuguese` language for NSIS windows installer. + +### Bug Fixes + +- [`c8700656b`](https://www.github.com/tauri-apps/tauri/commit/c8700656be3001a0cc6e087f23aebd482430a85b) ([#11985](https://www.github.com/tauri-apps/tauri/pull/11985) by [@ShaunSHamilton](https://www.github.com/tauri-apps/tauri/../../ShaunSHamilton)) Fix `tauri remove` from removing object type (`{}`) permissions. +- [`0ae06c5ca`](https://www.github.com/tauri-apps/tauri/commit/0ae06c5ca89cecd24154affdc69668f5e1e67d85) ([#11914](https://www.github.com/tauri-apps/tauri/pull/11914) by [@wtto00](https://www.github.com/tauri-apps/tauri/../../wtto00)) Fix the exclude path in file `Cargo.toml` of plugin template generated by cli. Path changed in [#9346](https://github.com/tauri-apps/tauri/pull/9346) + +### Dependencies + +- Upgraded to `tauri-cli@2.2.0` + +## \[2.1.0] + +### New Features + +- [`6bf917941`](https://www.github.com/tauri-apps/tauri/commit/6bf917941ff0fcc49e86b3ba427340b75f3ce49c) ([#11322](https://www.github.com/tauri-apps/tauri/pull/11322) by [@ShaunSHamilton](https://www.github.com/tauri-apps/tauri/../../ShaunSHamilton)) Add `tauri remove` to remove plugins from projects. +- [`058c0db72`](https://www.github.com/tauri-apps/tauri/commit/058c0db72f43fbe1574d0db654560e693755cd7e) ([#11584](https://www.github.com/tauri-apps/tauri/pull/11584) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `bundle > linux > rpm > compression` config option to control RPM bundle compression type and level. + +### Enhancements + +- [`1f311832a`](https://www.github.com/tauri-apps/tauri/commit/1f311832ab5b2d62a533dfcf9b1d78bddf249ae8) ([#11405](https://www.github.com/tauri-apps/tauri/pull/11405) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add more context for errors when decoding secret and public keys for signing updater artifacts. +- [`e0d1307d3`](https://www.github.com/tauri-apps/tauri/commit/e0d1307d3f78987d0059921a5ab01ea4b26e0ef1) ([#11414](https://www.github.com/tauri-apps/tauri/pull/11414) by [@Czxck001](https://www.github.com/tauri-apps/tauri/../../Czxck001)) Migrate the `$schema` Tauri configuration to the v2 format. +- [`c43d5df15`](https://www.github.com/tauri-apps/tauri/commit/c43d5df15828ecffa606482ea2b60350c488c981) ([#11512](https://www.github.com/tauri-apps/tauri/pull/11512) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Associate a newly created capability file with the `main` window on the `tauri add` and `tauri permission add` commands. + +### Bug Fixes + +- [`7af01ff2c`](https://www.github.com/tauri-apps/tauri/commit/7af01ff2ce623d727cd13a4c8a549c1c80031882) ([#11523](https://www.github.com/tauri-apps/tauri/pull/11523) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `tauri migrate` failing to install NPM depenencies when running from Deno. +- [`100a4455a`](https://www.github.com/tauri-apps/tauri/commit/100a4455aa48df508510bbc08273215bdf70c012) ([#11529](https://www.github.com/tauri-apps/tauri/pull/11529) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix detecting yarn berry (v2 and higher) in various tauri cli commands. +- [`60e86d5f6`](https://www.github.com/tauri-apps/tauri/commit/60e86d5f6e0f0c769d34ef368cd8801a918d796d) ([#11624](https://www.github.com/tauri-apps/tauri/pull/11624) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Use the public network IP address on `android dev` by default on Windows. + +### Dependencies + +- Upgraded to `tauri-cli@2.1.0` + +## \[2.0.4] + +### Enhancements + +- [`e4c9268b1`](https://www.github.com/tauri-apps/tauri/commit/e4c9268b19c614dc9ebb0895448fd16de7efee80) ([#11258](https://www.github.com/tauri-apps/tauri/pull/11258) by [@regexident](https://www.github.com/tauri-apps/tauri/../../regexident)) Support custom project directory structure where the Tauri app folder is not a subfolder of the frontend project. + The frontend and Tauri app project paths can be set with the `TAURI_FRONTEND_PATH` and the `TAURI_APP_PATH` environment variables respectively. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.4` + +## \[2.0.3] + +### New Features + +- [`eda5713ea`](https://www.github.com/tauri-apps/tauri/commit/eda5713eab78d28182071ea25ceca5f1994f37ea) ([#11242](https://www.github.com/tauri-apps/tauri/pull/11242) by [@alex-sandri](https://www.github.com/tauri-apps/tauri/../../alex-sandri)) Add `Italian` to supported NSIS installer languages +- [`b3563e3d6`](https://www.github.com/tauri-apps/tauri/commit/b3563e3d6ae8dc90ee68f25f575cd5538ab1915b) ([#11304](https://www.github.com/tauri-apps/tauri/pull/11304) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add Deno support in tauri-cli operations. + +### Bug Fixes + +- [`d609bef9f`](https://www.github.com/tauri-apps/tauri/commit/d609bef9fd7cd6eeb2bd701558100bd9cfb6e6f6) ([#11314](https://www.github.com/tauri-apps/tauri/pull/11314) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix android invalid proguard file when using an `identifier` that contains a component that is a reserved kotlin keyword, like `in`, `class`, etc +- [`069c05e44`](https://www.github.com/tauri-apps/tauri/commit/069c05e44fd6f30083fdc00dd6c0001278898592) ([#11315](https://www.github.com/tauri-apps/tauri/pull/11315) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix CLI crashing and failing to find a `.ico` file when `bundle > icon` option is using globs and doesn't have a string that ends with `.ico`. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.3` + +## \[2.0.2] + +### What's Changed + +- [`4475fbb50`](https://www.github.com/tauri-apps/tauri/commit/4475fbb502c5ffb3cea4de6bef1c7869be39bed6) ([#11208](https://www.github.com/tauri-apps/tauri/pull/11208) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Update cargo-mobile2 to 0.17.3, fixing lib name validation. +- [`a49a19ffa`](https://www.github.com/tauri-apps/tauri/commit/a49a19ffa304f031fb1a04d31a567cc7f42a380a) ([#11218](https://www.github.com/tauri-apps/tauri/pull/11218)) Fix bundling `appimage`, `deb` and `rpm` bundles failing to open when using `mainBinaryName` with spaces. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.2` + +## \[2.0.1] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.1` + +## \[2.0.0] + +### What's Changed + +- [`637285790`](https://www.github.com/tauri-apps/tauri/commit/6372857905ae9c0aedb7f482ddf6cf9f9836c9f2) Promote to v2 stable! + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0` + +## \[2.0.0-rc.18] + +### Enhancements + +- [`a08e6ffa6`](https://www.github.com/tauri-apps/tauri/commit/a08e6ffa6fe499553be3c4c620726d6031cd6dd3) ([#11185](https://www.github.com/tauri-apps/tauri/pull/11185) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Enhance port forwarding on `android dev` to be more resilient and tolerate delays when booting up devices. +- [`6cfe7edf6`](https://www.github.com/tauri-apps/tauri/commit/6cfe7edf63636fdf66c429efdeb7bc9a0f404e9f) ([#11186](https://www.github.com/tauri-apps/tauri/pull/11186) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Retain logger verbosity on the `android-studio-script` and `xcode-script` commands. +- [`60a5aea53`](https://www.github.com/tauri-apps/tauri/commit/60a5aea53db02ae6af325812ab97555f2c013d70) ([#11181](https://www.github.com/tauri-apps/tauri/pull/11181) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Set the `TRUNK_SERVE_ADDRESS` environment variable when running on iOS physical devices to support Trunk. + +### Bug Fixes + +- [`f5d61822b`](https://www.github.com/tauri-apps/tauri/commit/f5d61822bf5988827776dd58bed75c19364e86bd) ([#11184](https://www.github.com/tauri-apps/tauri/pull/11184) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS application not including the provided capabilities (entitlements). + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.18` + +## \[2.0.0-rc.17] + +### New Features + +- [`a944b9b05`](https://www.github.com/tauri-apps/tauri/commit/a944b9b05bc5ae6125ff451e86c5b207c511f3d7) ([#11118](https://www.github.com/tauri-apps/tauri/pull/11118) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `--github-workflows` flag for `tauri plugin new/init`. +- [`f57a729cd`](https://www.github.com/tauri-apps/tauri/commit/f57a729cd8f7e10d8daf0b9d5b85f9c7ad530496) ([#11039](https://www.github.com/tauri-apps/tauri/pull/11039) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `tauri inspect wix-upgrade-code` to print default Upgrade Code for your MSI installer derived from `productName`. + +### Bug Fixes + +- [`62b52f60a`](https://www.github.com/tauri-apps/tauri/commit/62b52f60a22ef84c4a2a2d9e662038b49f58e16c) ([#11064](https://www.github.com/tauri-apps/tauri/pull/11064) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `tauri add` failing to add NPM depenency with `npm` package manager. +- [`56e087471`](https://www.github.com/tauri-apps/tauri/commit/56e087471a347f6bee7422221a956925c60b17e3) ([#11100](https://www.github.com/tauri-apps/tauri/pull/11100) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix iOS xcode-script usage with `bun`. +- [`b88e22a5f`](https://www.github.com/tauri-apps/tauri/commit/b88e22a5fe4e2e4376d6cad64d1e74d104ca8927) ([#11063](https://www.github.com/tauri-apps/tauri/pull/11063) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) The cli now only sets the iOS deployment target environment variable when building for iOS. +- [`8d22c0c81`](https://www.github.com/tauri-apps/tauri/commit/8d22c0c814e7227d5e56ce9a08929045ccea1a1b) ([#11101](https://www.github.com/tauri-apps/tauri/pull/11101) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Only modify the iOS Xcode project "sign style" if we need to enforce manual signing. +- [`df24cb944`](https://www.github.com/tauri-apps/tauri/commit/df24cb944249ee398f6c8ba8c19757b398eec701) ([#11168](https://www.github.com/tauri-apps/tauri/pull/11168) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes Xcode pbxproj file parsing not expecting `_` in build configuration IDs. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.17` + +### Breaking Changes + +- [`a944b9b05`](https://www.github.com/tauri-apps/tauri/commit/a944b9b05bc5ae6125ff451e86c5b207c511f3d7) ([#11118](https://www.github.com/tauri-apps/tauri/pull/11118) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) `tauri plugin init/new` will no longer generate a `.github` directory with workflows by default, instead use the new `--github-workflows` flag. + +## \[2.0.0-rc.16] + +### New Features + +- [`9bb8fc618`](https://www.github.com/tauri-apps/tauri/commit/9bb8fc6189a93bcb811588b36e710d0f7818a1f9) ([#11030](https://www.github.com/tauri-apps/tauri/pull/11030) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add `--no-example` flag for `tauri plugin new` and `tauri plugin init` to disable creation of an example project. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.16` + +## \[2.0.0-rc.15] + +### Enhancements + +- [`5a0e922d4`](https://www.github.com/tauri-apps/tauri/commit/5a0e922d40dc3b7d9a8e3a65ccaf76d09f026cb8) ([#11007](https://www.github.com/tauri-apps/tauri/pull/11007) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Automatically discover the `src-tauri/src/main.rs` binary when it is not explicitly defined in the Cargo manifest bin array. + +### Bug Fixes + +- [`94e9d476e`](https://www.github.com/tauri-apps/tauri/commit/94e9d476ef506b1b8c09f55b81620c7839f98086) ([#11011](https://www.github.com/tauri-apps/tauri/pull/11011) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `main_binary_name` in custom wix and nsis templates including `.exe` + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.15` + +## \[2.0.0-rc.14] + +### Enhancements + +- [`6c5340f8b`](https://www.github.com/tauri-apps/tauri/commit/6c5340f8b2549dfe89f19656304e65cd670afc92) ([#11004](https://www.github.com/tauri-apps/tauri/pull/11004) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added the `log` plugin to the app template, which is required to visualize logs on Android and iOS. +- [`3ad2427dc`](https://www.github.com/tauri-apps/tauri/commit/3ad2427dc08f12c61edc726b587acce32eca1080) ([#10961](https://www.github.com/tauri-apps/tauri/pull/10961) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Only render app logs on iOS unless `-vv` is provided to the `ios dev` command. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.13` + +## \[2.0.0-rc.13] + +### Bug Fixes + +- [`a5848af65`](https://www.github.com/tauri-apps/tauri/commit/a5848af65b10d89686314cf737b7fd9d91f99dd8) ([#10944](https://www.github.com/tauri-apps/tauri/pull/10944) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Synchronize app version (`tauri.conf.json > version` or `Cargo.toml > package > version`) with the `CFBundleVersion` and `CFBundleShortVersionString` Info.plist values. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.12` + +## \[2.0.0-rc.12] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.11` + +## \[2.0.0-rc.11] + +### Enhancements + +- [`9c9644d15`](https://www.github.com/tauri-apps/tauri/commit/9c9644d155818d9efcad65b60aa985a59e767922) ([#10845](https://www.github.com/tauri-apps/tauri/pull/10845) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Enhance iOS library validation, checking libs built with link time optimization. + +### Bug Fixes + +- [`b42683592`](https://www.github.com/tauri-apps/tauri/commit/b42683592d446f25c2005b59e9e3ec551175906d) ([#10847](https://www.github.com/tauri-apps/tauri/pull/10847) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `ios build --target [aarch64-sim | x86_64]` failing to generate the app bundle for the iOS simulator. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.10` + +## \[2.0.0-rc.10] + +### Bug Fixes + +- [`6faa03276`](https://www.github.com/tauri-apps/tauri/commit/6faa032766b23cd161503905d4c79365ff6c50d1) ([#10854](https://www.github.com/tauri-apps/tauri/pull/10854) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes iOS code signing failing on CI due to a missing development certificate. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.9` + +## \[2.0.0-rc.9] + +### Bug Fixes + +- [`5af1f5dec`](https://www.github.com/tauri-apps/tauri/commit/5af1f5dec1bb98f335169df8c5e30c19a24cae07) ([#10851](https://www.github.com/tauri-apps/tauri/pull/10851) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `ios build` failing to build iOS app in CI when using an API key for automatic signing. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.9` + +## \[2.0.0-rc.8] + +### New Features + +- [`91e9e784a`](https://www.github.com/tauri-apps/tauri/commit/91e9e784aa59634e3fe6359f8b78d071d76a9e42) ([#10729](https://www.github.com/tauri-apps/tauri/pull/10729) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add plugins information in `tauri info` output +- [`09e9dc1aa`](https://www.github.com/tauri-apps/tauri/commit/09e9dc1aab1b66aa6a3a009d5873db586abe76a0) ([#10752](https://www.github.com/tauri-apps/tauri/pull/10752) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Allow Xcode to manage iOS code sign and provisioning profiles by default. + On CI, the `APPLE_API_KEY`, `APPLE_API_ISSUER` and `APPLE_API_KEY_PATH` environment variables must be provided for authentication. + +### Enhancements + +- [`3a4972b39`](https://www.github.com/tauri-apps/tauri/commit/3a4972b394c65c32eefebfb2181ba56b0cfc08f7) ([#10793](https://www.github.com/tauri-apps/tauri/pull/10793) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Include architecture in the `tauri info` output. +- [`fd68b7fde`](https://www.github.com/tauri-apps/tauri/commit/fd68b7fdea3890d9f0a373a252a3682bd9d04138) ([#10785](https://www.github.com/tauri-apps/tauri/pull/10785) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Remove the `.cargo/config` file creation that used to fix mobile build caches. +- [`f67a9eb6d`](https://www.github.com/tauri-apps/tauri/commit/f67a9eb6de4567c2374b8cdbabadcf0ca44d28fb) ([#10802](https://www.github.com/tauri-apps/tauri/pull/10802) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Synchronize identifier, development team and lib name with the iOS Xcode project. + +### Bug Fixes + +- [`83ed090bf`](https://www.github.com/tauri-apps/tauri/commit/83ed090bfa58a1784495f474d93b16a568be513f) ([#10790](https://www.github.com/tauri-apps/tauri/pull/10790) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Do not quit `ios dev` and `android dev` process when we fail to attach the logger. +- [`2d31aef75`](https://www.github.com/tauri-apps/tauri/commit/2d31aef759f496f3afe46b7697176e61a8570511) ([#10751](https://www.github.com/tauri-apps/tauri/pull/10751) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Ensure gradlew is executable and does not use CRLF so it can be used on UNIX systems. +- [`02b2f964a`](https://www.github.com/tauri-apps/tauri/commit/02b2f964a70c61ff08b5052bd9fcde472d706d9c) ([#10795](https://www.github.com/tauri-apps/tauri/pull/10795) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix the `add` command NPM version specifier for known plugins from `2.0.0-rc` (unknown version requirement) to `^2.0.0-rc`. +- [`84070bae9`](https://www.github.com/tauri-apps/tauri/commit/84070bae92d234bc3630e795cfaf79f869f3a751) ([#10792](https://www.github.com/tauri-apps/tauri/pull/10792) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix `tauri plugin ios init` not generating the iOS folder. +- [`edb2ca31f`](https://www.github.com/tauri-apps/tauri/commit/edb2ca31f70a39004b6a09ae53425f22e243318e) ([#10794](https://www.github.com/tauri-apps/tauri/pull/10794) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Migrate v1 plugins NPM packages. +- [`9718dc9e8`](https://www.github.com/tauri-apps/tauri/commit/9718dc9e8c9bc91d9a5d9e0e06a7afab62492152) ([#10791](https://www.github.com/tauri-apps/tauri/pull/10791) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Reintroduce the `targetSdk` value in the Android application template. + +### What's Changed + +- [`fb6bf3142`](https://www.github.com/tauri-apps/tauri/commit/fb6bf314252c88dd49af74bdbb8499df370836ae) ([#10763](https://www.github.com/tauri-apps/tauri/pull/10763) by [@rdlabo](https://www.github.com/tauri-apps/tauri/../../rdlabo)) Update plugin template Android code to match documentation on Android package ID usage. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.8` + +### Breaking Changes + +- [`073bb4f45`](https://www.github.com/tauri-apps/tauri/commit/073bb4f459a923541b94970dfa7e087bccaa2cfd) ([#10772](https://www.github.com/tauri-apps/tauri/pull/10772) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Removed the deprecated `webview_fixed_runtime_path` config option, use the `webview_install_mode` instead. + +## \[2.0.0-rc.7] + +### Enhancements + +- [`da8c9a7d3`](https://www.github.com/tauri-apps/tauri/commit/da8c9a7d3069398c26826aeb082caa44b7c92809) ([#10669](https://www.github.com/tauri-apps/tauri/pull/10669) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Modify both ExportOptions.plist and project.pbxproj to reflect changes for the `IOS_CERTIFICATE`, `IOS_CERTIFICATE_PASSWORD` and `IOS_MOBILE_PROVISION` environment variables. + +### Bug Fixes + +- [`793ee0531`](https://www.github.com/tauri-apps/tauri/commit/793ee0531730597e6008c9c0dedabbab7a2bef53) ([#10700](https://www.github.com/tauri-apps/tauri/pull/10700) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Allow hyphens and underscores on app identifiers. +- [`da8c9a7d3`](https://www.github.com/tauri-apps/tauri/commit/da8c9a7d3069398c26826aeb082caa44b7c92809) ([#10669](https://www.github.com/tauri-apps/tauri/pull/10669) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Synchronize Xcode project changes with the ExportOptions.plist file so `ios build` calls can work with code signing changes made in Xcode. + +### What's Changed + +- [`f4d5241b3`](https://www.github.com/tauri-apps/tauri/commit/f4d5241b377d0f7a1b58100ee19f7843384634ac) ([#10731](https://www.github.com/tauri-apps/tauri/pull/10731) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Update documentation icon path. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.7` + +### Breaking Changes + +- [`da8c9a7d3`](https://www.github.com/tauri-apps/tauri/commit/da8c9a7d3069398c26826aeb082caa44b7c92809) ([#10669](https://www.github.com/tauri-apps/tauri/pull/10669) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) The `IOS_CERTIFICATE`, `IOS_CERTIFICATE_PASSWORD` and `IOS_MOBILE_PROVISION` environment variables are now read by the `ios build` command instead of `ios init`. + +## \[2.0.0-rc.6] + +### New Features + +- [`da381e07f`](https://www.github.com/tauri-apps/tauri/commit/da381e07f3770988fe6d0859a02331b87cc6723f) ([#10696](https://www.github.com/tauri-apps/tauri/pull/10696) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Inject configured resources on mobile apps. + +### Bug Fixes + +- [`1a60822a4`](https://www.github.com/tauri-apps/tauri/commit/1a60822a4220b6dbb1ad7295a2e37d6c3004edad) ([#10699](https://www.github.com/tauri-apps/tauri/pull/10699) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Changed the `add` command to use a version requirement that matches the CLI's stable and prerelease numbers. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.6` + +## \[2.0.0-rc.5] + +### New Features + +- [`8d148a9e2`](https://www.github.com/tauri-apps/tauri/commit/8d148a9e2566edebfea2d75f32df7c9396d765a4) ([#10634](https://www.github.com/tauri-apps/tauri/pull/10634) by [@anatawa12](https://www.github.com/tauri-apps/tauri/../../anatawa12)) Custom sign command with object notation for whitespaces in the command path and arguments. + +### Bug Fixes + +- [`8ae52a615`](https://www.github.com/tauri-apps/tauri/commit/8ae52a615a11d934930001da63ce6ac8442c7efc) ([#10676](https://www.github.com/tauri-apps/tauri/pull/10676) by [@rdlabo](https://www.github.com/tauri-apps/tauri/../../rdlabo)) Change plugin template call to `register_ios_plugin` params to snake case +- [`7796a8fc6`](https://www.github.com/tauri-apps/tauri/commit/7796a8fc649cd7397a67048c71f8d1fbf822122a) ([#10687](https://www.github.com/tauri-apps/tauri/pull/10687) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fix Swift plugin compilation on older versions. +- [`9b99ebab1`](https://www.github.com/tauri-apps/tauri/commit/9b99ebab17d6a043d82a7aeecfb76c56a995c287) ([#10431](https://www.github.com/tauri-apps/tauri/pull/10431) by [@mrguiman](https://www.github.com/tauri-apps/tauri/../../mrguiman)) Do not include the target arch when building and archiving the iOS application, + which makes Xcode project modifications more flexible. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.5` + +## \[2.0.0-rc.4] + +### New Features + +- [`78e22bedc`](https://www.github.com/tauri-apps/tauri/commit/78e22bedcab5096f1a4e667321fc8b2817b79214) ([#10602](https://www.github.com/tauri-apps/tauri/pull/10602) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Add necessary options to `AndroidManifest.xml` in android template to support AndroidTV. +- [`3bec7b159`](https://www.github.com/tauri-apps/tauri/commit/3bec7b1595e28630a22b9fb16540beafd5eb7969) ([#10544](https://www.github.com/tauri-apps/tauri/pull/10544) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) v1 migrate script now migrates Svelte and Vue.js code. + +### Enhancements + +- [`bba1a4419`](https://www.github.com/tauri-apps/tauri/commit/bba1a441917defcdf9e88221e9b0e1cdd744e77a) ([#10457](https://www.github.com/tauri-apps/tauri/pull/10457) by [@mmvanheusden](https://www.github.com/tauri-apps/tauri/../../mmvanheusden)) Added `--no-fmt` option to the `add` command to skip formatting the code after applying changes. +- [`71d00646a`](https://www.github.com/tauri-apps/tauri/commit/71d00646a9b7c52311ba087820e52fd19861b3d8) ([#10504](https://www.github.com/tauri-apps/tauri/pull/10504) by [@fu050409](https://www.github.com/tauri-apps/tauri/../../fu050409)) Improve the `init` command behavior by detecting the project NPM package manager. +- [`8deb1966a`](https://www.github.com/tauri-apps/tauri/commit/8deb1966ace93d1350f271d525a878ba4b0879ce) ([#10652](https://www.github.com/tauri-apps/tauri/pull/10652) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Infer macOS codesign identity from the `APPLE_CERTIFICATE` environment variable when provided, meaning the identity no longer needs to be provided when signing on CI using that option. If the imported certificate name does not match a provided signingIdentity configuration, an error is returned. +- [`f35bcda28`](https://www.github.com/tauri-apps/tauri/commit/f35bcda2895a1350df31853da76a051783b9fd3f) ([#10598](https://www.github.com/tauri-apps/tauri/pull/10598) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) `permission add` and `add` commands now check if the plugin is known and if it is either desktop or mobile only + we add the permission to a target-specific capability. + +### Bug Fixes + +- [`f712f31d1`](https://www.github.com/tauri-apps/tauri/commit/f712f31d1d21e85fab99194530702c70e45c63fc) ([#10639](https://www.github.com/tauri-apps/tauri/pull/10639) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Include notarization error output in the error message if it fails. +- [`9f75d0622`](https://www.github.com/tauri-apps/tauri/commit/9f75d06228fcb7036cf7a4e215abc7bc8d1a0a56) ([#10604](https://www.github.com/tauri-apps/tauri/pull/10604) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `android dev` port forward failing under some conditions, add better logging and error handling. +- [`2d47352a0`](https://www.github.com/tauri-apps/tauri/commit/2d47352a07a7d742e62291a5e6810aed79fc8b50) ([#10418](https://www.github.com/tauri-apps/tauri/pull/10418) by [@samkearney](https://www.github.com/tauri-apps/tauri/../../samkearney)) CLI commands will now consistently search for the `app_dir` (the directory containing `package.json`) from the current working directory of the command invocation. +- [`f4cd68f04`](https://www.github.com/tauri-apps/tauri/commit/f4cd68f040635f019ff989667289cfe9061c7dfb) ([#10600](https://www.github.com/tauri-apps/tauri/pull/10600) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `android dev` not working when using the builtin dev server. +- [`41c7a6646`](https://www.github.com/tauri-apps/tauri/commit/41c7a6646ba9afbb2322986fb39054a43a88e604) ([#10572](https://www.github.com/tauri-apps/tauri/pull/10572) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Exit with code 1 if a panic occurs when running the CLI with `bun`. +- [`9089d9763`](https://www.github.com/tauri-apps/tauri/commit/9089d97637e49bebbe7dba8adc6351e04b53a44d) ([#10605](https://www.github.com/tauri-apps/tauri/pull/10605) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes `[android|ios] build --config ` failing to resolve. +- [`712f1049f`](https://www.github.com/tauri-apps/tauri/commit/712f1049fae74bfda5f360adcee7210cea92fe63) ([#10569](https://www.github.com/tauri-apps/tauri/pull/10569) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `ios dev` and `ios build` using `bun`. +- [`3998570fd`](https://www.github.com/tauri-apps/tauri/commit/3998570fd3d03c1bb282bd060a4aafb4ab5437f9) ([#10540](https://www.github.com/tauri-apps/tauri/pull/10540) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes v1 migration of Cargo.toml dependencies and features. +- [`3beba92b5`](https://www.github.com/tauri-apps/tauri/commit/3beba92b5bdc62ed00c9f6a9b8f8c05cfa78f8dc) ([#10542](https://www.github.com/tauri-apps/tauri/pull/10542) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes v1 frontend code migration when using plugin default imports. +- [`10fb027b7`](https://www.github.com/tauri-apps/tauri/commit/10fb027b7590cf2c020b5c220328b9051c05adca) ([#10656](https://www.github.com/tauri-apps/tauri/pull/10656) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Migrate v1 plugins to their v2 releases. +- [`10fb027b7`](https://www.github.com/tauri-apps/tauri/commit/10fb027b7590cf2c020b5c220328b9051c05adca) ([#10656](https://www.github.com/tauri-apps/tauri/pull/10656) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Prevent duplicate permissions on v1 migration. +- [`b160f9359`](https://www.github.com/tauri-apps/tauri/commit/b160f9359d6f661d280185d2a2a4bdf280b8e72c) ([#10638](https://www.github.com/tauri-apps/tauri/pull/10638) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Only validate the output iOS library on debug builds. +- [`4bfe4880f`](https://www.github.com/tauri-apps/tauri/commit/4bfe4880fbef42d1a115f840e712d4a2f59c8ab3) ([#10550](https://www.github.com/tauri-apps/tauri/pull/10550) by [@anatawa12](https://www.github.com/tauri-apps/tauri/../../anatawa12)) fails to build universal fat binary if main bin is renamed to another name in `Cargo.toml` +- [`f3837d5b9`](https://www.github.com/tauri-apps/tauri/commit/f3837d5b98f0caebc3337f9a9e8127e7b96c3fc5) ([#10539](https://www.github.com/tauri-apps/tauri/pull/10539) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Improve migration tooling by supporting TOML configs, handle nulls and properly check for updater migration. + +### What's Changed + +- [`794cf8234`](https://www.github.com/tauri-apps/tauri/commit/794cf8234f8b620c74cbd23cc4b81be9b2edc386) ([#10571](https://www.github.com/tauri-apps/tauri/pull/10571) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Change iOS template default export method from deprecated `development` to `debugging`. +- [`bfc49cc7a`](https://www.github.com/tauri-apps/tauri/commit/bfc49cc7a1d43e3378e93865b9b37ce4bddfa6e6) ([#10558](https://www.github.com/tauri-apps/tauri/pull/10558) by [@ahqsoftwares](https://www.github.com/tauri-apps/tauri/../../ahqsoftwares)) Remove targetSdk from gradle files + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.4` + +## \[2.0.0-rc.3] + +### Enhancements + +- [`5f56cb0a8`](https://www.github.com/tauri-apps/tauri/commit/5f56cb0a8b9c6f695bc6439a8db997c98b3a3997) ([#10507](https://www.github.com/tauri-apps/tauri/pull/10507) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Update gradle to 8.9 and the gradle android plugin to 8.5.1 in the android templates (requires latest Android Studio). This should add support for Java 21 but Java 17 keeps being the recommended version. + +### Bug Fixes + +- [`f5dfc0280`](https://www.github.com/tauri-apps/tauri/commit/f5dfc02800dbd3bdee671b032454c49ac7102fb4) ([#10533](https://www.github.com/tauri-apps/tauri/pull/10533) by [@FabianLars](https://www.github.com/tauri-apps/tauri/../../FabianLars)) Fixed an issue causing `tauri ios init` to fail if `iOS.minimumSystemVersion` was not configured explicitly. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.3` + +## \[2.0.0-rc.2] + +### New Features + +- [`8dc81b6cc`](https://www.github.com/tauri-apps/tauri/commit/8dc81b6cc2b8235b11f74a971d6aa3a5df5e9f68) ([#10496](https://www.github.com/tauri-apps/tauri/pull/10496) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `bundle > ios > template` configuration option for custom Xcode project YML Handlebars template using XcodeGen. +- [`02c00abc6`](https://www.github.com/tauri-apps/tauri/commit/02c00abc63cf86e9bf9179cbb143d5145a9397b6) ([#10495](https://www.github.com/tauri-apps/tauri/pull/10495) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `bundle > ios > minimumSystemVersion` configuration option. + +### Enhancements + +- [`8e1e15304`](https://www.github.com/tauri-apps/tauri/commit/8e1e15304e9dc98d7f875fc8dceb7d4ce19adc47) ([#10483](https://www.github.com/tauri-apps/tauri/pull/10483) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Check if the Rust library contains the symbols required at runtime for Android and iOS apps. +- [`ca6868956`](https://www.github.com/tauri-apps/tauri/commit/ca68689564cbc8dfa9a5220d3daf81a44ef81fcc) ([#10479](https://www.github.com/tauri-apps/tauri/pull/10479) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Check if identifier or lib name changed when running mobile commands. + +### Bug Fixes + +- [`2e8ab7bac`](https://www.github.com/tauri-apps/tauri/commit/2e8ab7bac12046d734fb07a1b4fe5e03004b305e) ([#10481](https://www.github.com/tauri-apps/tauri/pull/10481) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Migration from v1 to v2 now adds the updater plugin when it is active. + +### What's Changed + +- [`a3cd9779a`](https://www.github.com/tauri-apps/tauri/commit/a3cd9779a47428e306a628d658740669faf69ccd) ([#10480](https://www.github.com/tauri-apps/tauri/pull/10480) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Removed the `[android|ios] open` command. It is recommended to use `[android|ios] dev --open` or `[android|ios] build --open` instead. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.2` + +## \[2.0.0-rc.1] + +### Bug Fixes + +- [`fb1933f17`](https://www.github.com/tauri-apps/tauri/commit/fb1933f17442674e53374578e57a8cad241ac3c6) ([#10467](https://www.github.com/tauri-apps/tauri/pull/10467) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `android dev --open`. +- [`206914fe8`](https://www.github.com/tauri-apps/tauri/commit/206914fe8d97eb61a2ff2a80e94e65e7a42bcea5) ([#10466](https://www.github.com/tauri-apps/tauri/pull/10466) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Fixes running `adb reverse` in Node.js context. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.1` + +## \[2.0.0-rc.0] + +### New Features + +- [`d5511c311`](https://www.github.com/tauri-apps/tauri/commit/d5511c3117b1a117cb0b7359c5fa09aa4795122b) ([#10395](https://www.github.com/tauri-apps/tauri/pull/10395)) Added migration from `2.0.0-beta` to `2.0.0-rc`. +- [`a5bfbaa62`](https://www.github.com/tauri-apps/tauri/commit/a5bfbaa62b8cd0aacbb33f730d4e30b43c461fe1)([#9962](https://www.github.com/tauri-apps/tauri/pull/9962)) Added `bundle > iOS > frameworks` configuration to define a list of frameworks that are linked to the Xcode project when it is generated. + +### Enhancements + +- [`a0841d509`](https://www.github.com/tauri-apps/tauri/commit/a0841d509abc43b62bb7c755e8727f3f461862d1) ([#10421](https://www.github.com/tauri-apps/tauri/pull/10421)) Changes the default behavior of the `dev` command to only expose to localhost (`127.0.0.1`) instead of the default system interface. + +### Security fixes + +- [`289ae5555`](https://www.github.com/tauri-apps/tauri/commit/289ae5555da3802741018015bfe4927729a2eb33) ([#10386](https://www.github.com/tauri-apps/tauri/pull/10386)) Re-enable TLS checks that were previously disabled to support an insecure HTTPS custom protocol on Android which is no longer used. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-rc.0` + +### Breaking Changes + +- [`758d28c8a`](https://www.github.com/tauri-apps/tauri/commit/758d28c8a2d5c9567158e339326b765f72da983e) ([#10390](https://www.github.com/tauri-apps/tauri/pull/10390)) Core plugin permissions are now prefixed with `core:`, the `core:default` permission set can now be used and the `core` plugin name is reserved. + The `tauri migrate` tool will automate the migration process, which involves prefixing all `app`, `event`, `image`, `menu`, `path`, `resources`, `tray`, `webview` and `window` permissions with `core:`. +- [`7ba67b4ac`](https://www.github.com/tauri-apps/tauri/commit/7ba67b4aca8d3f3b1aa5ad08819605029d36e6b4)([#10437](https://www.github.com/tauri-apps/tauri/pull/10437)) `ios dev` and `android dev` now uses localhost for the development server unless running on an iOS device, + which still requires connecting to the public network address. To conditionally check this on your frontend + framework's configuration you can check for the existence of the `TAURI_DEV_HOST` + environment variable instead of checking if the target is iOS or Android (previous recommendation). + +## \[2.0.0-beta.23] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.23` + +## \[2.0.0-beta.22] + +### New Features + +- [`7c7fa0964`](https://www.github.com/tauri-apps/tauri/commit/7c7fa0964db3403037fdb9a34de2b877ddb8df1c) ([#9963](https://www.github.com/tauri-apps/tauri/pull/9963) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Added `--method` argument for `ios build` to select the export options' method. +- [`7c7fa0964`](https://www.github.com/tauri-apps/tauri/commit/7c7fa0964db3403037fdb9a34de2b877ddb8df1c) ([#9963](https://www.github.com/tauri-apps/tauri/pull/9963) by [@lucasfernog](https://www.github.com/tauri-apps/tauri/../../lucasfernog)) Setup iOS signing by reading `IOS_CERTIFICATE`, `IOS_CERTIFICATE_PASSWORD` and `IOS_MOBILE_PROVISION` environment variables. + +### Enhancements + +- [`c01e87ad4`](https://www.github.com/tauri-apps/tauri/commit/c01e87ad46e2a5b3fb8d018739e724ef932008d7) ([#10198](https://www.github.com/tauri-apps/tauri/pull/10198) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Enhance `tauri migrate` to also migrate variables like `appWindow`: + + ```ts + import { appWindow } from '@tauri-apps/api/window' + ``` + + will become: + + ```ts + import { getCurrentWebviewWindow } from '@tauri-apps/api/webviewWindow' + const appWindow = getCurrentWebviewWindow() + ``` + +### Bug Fixes + +- [`94136578b`](https://www.github.com/tauri-apps/tauri/commit/94136578bc89e4b973c471050ae9c2d83ffcb7c6) ([#10186](https://www.github.com/tauri-apps/tauri/pull/10186) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `migrate` command, migrating incorrect permissions for `clipboard`. +- [`c01e87ad4`](https://www.github.com/tauri-apps/tauri/commit/c01e87ad46e2a5b3fb8d018739e724ef932008d7) ([#10198](https://www.github.com/tauri-apps/tauri/pull/10198) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix `tauri migrate` incorrectly migrating `@tauri-apps/api/tauri` module to just `core` and `@tauri-apps/api/window` to just `webviewWindow`. +- [`15e125996`](https://www.github.com/tauri-apps/tauri/commit/15e12599667b749c3d7cd2259e6cf7c7b5c6e2be) ([#10234](https://www.github.com/tauri-apps/tauri/pull/10234) by [@amrbashir](https://www.github.com/tauri-apps/tauri/../../amrbashir)) Fix cli failing to detect the correct cargo target directory when using cargo `--target-dir` flag with `tauri build` or `tauri dev` + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.22` + +## \[2.0.0-beta.21] + +### New Features + +- [`656a64974`](https://www.github.com/tauri-apps/tauri/commit/656a64974468bc207bf39537e02ae179bdee9b83) ([#9318](https://www.github.com/tauri-apps/tauri/pull/9318)) Added a configuration option to disable hardened runtime on macOS codesign. + +### Enhancements + +- [`f44a2ec47`](https://www.github.com/tauri-apps/tauri/commit/f44a2ec47c13243d472fa08a9df8b20d8490d79f) ([#10030](https://www.github.com/tauri-apps/tauri/pull/10030)) Enhance the plugin template to include `permissions/default.toml` and default capabilities file for the example application. + +### Bug Fixes + +- [`019a74e97`](https://www.github.com/tauri-apps/tauri/commit/019a74e970958d29cf69a6f24669d603399dcbb3) ([#9931](https://www.github.com/tauri-apps/tauri/pull/9931)) Fix wrong migration of `clipboard` and `globalShortcut` modules +- [`27838365a`](https://www.github.com/tauri-apps/tauri/commit/27838365a6841b0d3fa645ba2528221d23d4aeb2) ([#10135](https://www.github.com/tauri-apps/tauri/pull/10135)) Fix parsing of cargo profile when using `--profile=` syntax. +- [`79542f4d4`](https://www.github.com/tauri-apps/tauri/commit/79542f4d4542bd97451da7605de16e8464d6a06c) ([#10039](https://www.github.com/tauri-apps/tauri/pull/10039)) Fixed an issue that prevented `tauri icon` from rendering `` nodes in SVG files. +- [`40c0f44e1`](https://www.github.com/tauri-apps/tauri/commit/40c0f44e1c74c18ed0d6c645724d650637725456) ([#9971](https://www.github.com/tauri-apps/tauri/pull/9971)) Changed the deployment target of plugin iOS Xcode project to 13.0 so it works on older iOS releases. +- [`f56cdc9e3`](https://www.github.com/tauri-apps/tauri/commit/f56cdc9e391c4d55e4d7e935203d0f891864f22d) ([#10016](https://www.github.com/tauri-apps/tauri/pull/10016)) Add missing dependency `libayatana-appindicator3.so.1` for rpm package. +- [`1601da5b5`](https://www.github.com/tauri-apps/tauri/commit/1601da5b525de05cb813002d611f22ea4217a4fb) ([#10114](https://www.github.com/tauri-apps/tauri/pull/10114)) Removed alpha channel from default icons in iOS template to comply with Apple's human interface guideline + (https://developer.apple.com/design/human-interface-guidelines/app-icons), because + transparent icons with alpha channel are not allowed, and will be rejected + upon upload to Apple appstore. + +### What's Changed + +- [`3cca5c2be`](https://www.github.com/tauri-apps/tauri/commit/3cca5c2be88bbd52139e7dda371e88510d28bc8e) ([#9924](https://www.github.com/tauri-apps/tauri/pull/9924)) Migrate to new Android buildFeatures.buildConfig format. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.21` +- [`f955f7b49`](https://www.github.com/tauri-apps/tauri/commit/f955f7b4903bcea376c0a8b430736f66c8cebf56) ([#9929](https://www.github.com/tauri-apps/tauri/pull/9929)) Switch from `dirs_next` to `dirs` as `dirs_next` is now unmaintained while `dirs` is + +### Breaking Changes + +- [`911242f09`](https://www.github.com/tauri-apps/tauri/commit/911242f0928e0a2add3595fa9de27850fb875fa6) ([#9883](https://www.github.com/tauri-apps/tauri/pull/9883)) Move updater target from `bundle > targets` to a separate field `bundle > createUpdaterArtifacts` + +## \[2.0.0-beta.20] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.20` + +## \[2.0.0-beta.19] + +### New Features + +- [`8a1ae2dea`](https://www.github.com/tauri-apps/tauri/commit/8a1ae2deaf3086e531ada25b1627f900e2e421fb)([#9843](https://www.github.com/tauri-apps/tauri/pull/9843)) Added an option to use a Xcode project for the iOS plugin instead of a plain SwiftPM project. +- [`9e4b2253f`](https://www.github.com/tauri-apps/tauri/commit/9e4b2253f6ddaccd0f5c88734287bd5c84d4936a)([#9734](https://www.github.com/tauri-apps/tauri/pull/9734)) Add `tauri bundle` subcommand which runs the bundle phase only, best paired with `tauri build --no-bundle` + +### Enhancements + +- [`8b032c3cf`](https://www.github.com/tauri-apps/tauri/commit/8b032c3cf638e64e50df9d9cf8bc789c7e285987)([#9896](https://www.github.com/tauri-apps/tauri/pull/9896)) Add a blank LaunchScreen.storyboard to the iOS project init template to pass the App Store validation. +- [`9970d88be`](https://www.github.com/tauri-apps/tauri/commit/9970d88becee1560a4b2a7ffc1fe65991a42a8c9)([#9892](https://www.github.com/tauri-apps/tauri/pull/9892)) Update to latest gradle. + +### What's Changed + +- [`80aa50498`](https://www.github.com/tauri-apps/tauri/commit/80aa504987dd9cfa59aa5848c4d7960e1d58d0e6)([#9870](https://www.github.com/tauri-apps/tauri/pull/9870)) Updated Android target SDK to 34. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.19` + +### Breaking Changes + +- [`265c23886`](https://www.github.com/tauri-apps/tauri/commit/265c23886ee5efbcc6d7188ff5c84cb32fa82aea)([#9375](https://www.github.com/tauri-apps/tauri/pull/9375)) Avoid renaming main binary to product name and perserve the name generated by cargo. +- [`1df5cdeb0`](https://www.github.com/tauri-apps/tauri/commit/1df5cdeb06f5464e0eec4055e21b7b7bc8739eed)([#9858](https://www.github.com/tauri-apps/tauri/pull/9858)) Use `tauri.conf.json > identifier` to set the `PackageName` in Android and `BundleId` in iOS. + +## \[2.0.0-beta.18] + +### Bug Fixes + +- [`beda18bce`](https://www.github.com/tauri-apps/tauri/commit/beda18bce95fd6e10543b2d8f1eca5fb7ca0655b)([#9855](https://www.github.com/tauri-apps/tauri/pull/9855)) Fixed an issue that caused `tauri add` to fail for multiple rust-only and platform-specific plugins. +- [`4a33bc6a6`](https://www.github.com/tauri-apps/tauri/commit/4a33bc6a62d2ed9371191c8a7f78ff3f33930455)([#9553](https://www.github.com/tauri-apps/tauri/pull/9553)) Fixes `pnpm` detection when initializing and running a mobile project. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.18` + +## \[2.0.0-beta.17] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.17` + +## \[2.0.0-beta.16] + +### Bug Fixes + +- [`97ec422f2`](https://www.github.com/tauri-apps/tauri/commit/97ec422f22d069b9570931834241c7e47bc68cc3)([#9638](https://www.github.com/tauri-apps/tauri/pull/9638)) Exit `tauri icon` with non-zero code when it fails. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.16` + +## \[2.0.0-beta.15] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.15` + +## \[2.0.0-beta.14] + +### Enhancements + +- [`8a63ceb4f`](https://www.github.com/tauri-apps/tauri/commit/8a63ceb4f31c422311b0f7dff173a9c8c0e1a604)([#9473](https://www.github.com/tauri-apps/tauri/pull/9473)) Ignore `.DS_Store` by default for `tauri dev` hot reloads. + +### Bug Fixes + +- [`e64b8f1dc`](https://www.github.com/tauri-apps/tauri/commit/e64b8f1dcedad3222f46755bf6f30392a7ec2f90)([#9479](https://www.github.com/tauri-apps/tauri/pull/9479)) Upgrade `heck` to v0.5 to better support Chinese and Japanese product name, because Chinese do not have word separation. +- [`aaa332c6e`](https://www.github.com/tauri-apps/tauri/commit/aaa332c6e78c956debd11efda021a0406621a01d)([#9540](https://www.github.com/tauri-apps/tauri/pull/9540)) Fix `tauri migrate` trying to migrate to a non-existing plugin. +- [`e64b8f1dc`](https://www.github.com/tauri-apps/tauri/commit/e64b8f1dcedad3222f46755bf6f30392a7ec2f90)([#9479](https://www.github.com/tauri-apps/tauri/pull/9479)) Fixed an issue causing the `build.runner` and `build.features` configs to not take effect. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.14` + +## \[2.0.0-beta.13] + +### Bug Fixes + +- [`73c1c2d33`](https://www.github.com/tauri-apps/tauri/commit/73c1c2d33872651c32c761c838714b684980c668)([#9457](https://www.github.com/tauri-apps/tauri/pull/9457)) Gracefully handle Non-UTF8 files when using `tauri migrate` +- [`9331435a5`](https://www.github.com/tauri-apps/tauri/commit/9331435a50cc3769720bd2671da8510699d28671)([#9412](https://www.github.com/tauri-apps/tauri/pull/9412)) Fix `tauri info` crashing when Node.js is not installed. + +### What's Changed + +- [`8f4b1050c`](https://www.github.com/tauri-apps/tauri/commit/8f4b1050c4de0e9194680408ff3a6902b67045f8)([#9459](https://www.github.com/tauri-apps/tauri/pull/9459)) Show full expected path of `frontendDist` when if can't be found. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.13` + +## \[2.0.0-beta.12] + +### New Features + +- [`93e0e1392`](https://www.github.com/tauri-apps/tauri/commit/93e0e1392ec341fcadf696c03e78f0ca1e73c941) Support specifying a version for `tauri add` subcommand, for example: `tauri add window-state@2.0.0-beta.2` + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.12` + +## \[2.0.0-beta.11] + +### Enhancements + +- [`ac76a22f3`](https://www.github.com/tauri-apps/tauri/commit/ac76a22f383028d9bacdedebeb41d3fca5ec9dac)([#9183](https://www.github.com/tauri-apps/tauri/pull/9183)) Allow empty responses for `devUrl`, `beforeDevCommand` and `beforeBuildCommands` questions in `tauri init`. +- [`b525ddadf`](https://www.github.com/tauri-apps/tauri/commit/b525ddadf7e7588c3e195cf0f821c9862c545d06)([#9237](https://www.github.com/tauri-apps/tauri/pull/9237)) `openssl` is no longer a required dependency on macOS. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.11` + +## \[2.0.0-beta.10] + +### New Features + +- [`7213b9e47`](https://www.github.com/tauri-apps/tauri/commit/7213b9e47242bef814aa7257e0bf84631bf5fe7e)([#9124](https://www.github.com/tauri-apps/tauri/pull/9124)) Add default permission for a plugin to capabilities when using `tauri add `. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.10` + +## \[2.0.0-beta.9] + +### Bug Fixes + +- [`c3ea3a2b7`](https://www.github.com/tauri-apps/tauri/commit/c3ea3a2b7d2fe3085f05b63dd1feb962beb4b7b3)([#9126](https://www.github.com/tauri-apps/tauri/pull/9126)) Fix bundling when `plugins > updater > windows > installerArgs` are set in `tauri.conf.json` + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.9` + +## \[2.0.0-beta.8] + +### Enhancements + +- [`3e472d0af`](https://www.github.com/tauri-apps/tauri/commit/3e472d0afcd67545dd6d9f18d304580a3b2759a8)([#9115](https://www.github.com/tauri-apps/tauri/pull/9115)) Changed the permission and capability platforms to be optional. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.8` + +## \[2.0.0-beta.7] + +### Enhancements + +- [`c68218b36`](https://www.github.com/tauri-apps/tauri/commit/c68218b362c417b62e56c7a2b5b32c13fe035a83)([#8990](https://www.github.com/tauri-apps/tauri/pull/8990)) Add `--no-bundle` flag for `tauri build` command to skip bundling. Previously `none` was used to skip bundling, it will now be treated as invalid format and a warning will be emitted instead. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.7` + +## \[2.0.0-beta.6] + +### Bug Fixes + +- [`f5f3ed5f`](https://www.github.com/tauri-apps/tauri/commit/f5f3ed5f6faa0b51e83244acc15e9006299a03ba)([#9009](https://www.github.com/tauri-apps/tauri/pull/9009)) Fixes Android and iOS project initialization when the Tauri CLI is on a different disk partition. +- [`d7d03c71`](https://www.github.com/tauri-apps/tauri/commit/d7d03c7197212f3a5bebe08c929417d60927eb89)([#9017](https://www.github.com/tauri-apps/tauri/pull/9017)) Fixes dev watcher on mobile dev. +- [`b658ded6`](https://www.github.com/tauri-apps/tauri/commit/b658ded614cfc169228cb22ad5bfc64478dfe161)([#9015](https://www.github.com/tauri-apps/tauri/pull/9015)) Fixes truncation of existing BuildTask.kt when running `tauri android init`. + +### What's Changed + +- [`3657ad82`](https://www.github.com/tauri-apps/tauri/commit/3657ad82f88ce528551d032d521c52eed3f396b4)([#9008](https://www.github.com/tauri-apps/tauri/pull/9008)) Updates to new ACL manifest path. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.6` + +## \[2.0.0-beta.5] + +### New Features + +- [`06d63d67`](https://www.github.com/tauri-apps/tauri/commit/06d63d67a061459dd533ddcae755922427a6dfc5)([#8827](https://www.github.com/tauri-apps/tauri/pull/8827)) Add new subcommands for managing permissions and cababilities: + + - `tauri permission new` + - `tauri permission add` + - `tauri permission rm` + - `tauri permission ls` + - `tauri capability new` + +### Breaking Changes + +- [`b9e6a018`](https://www.github.com/tauri-apps/tauri/commit/b9e6a01879d9233040f3d3fab11c59e70563da7e)([#8937](https://www.github.com/tauri-apps/tauri/pull/8937)) The `custom-protocol` Cargo feature is no longer required on your application and is now ignored. To check if running on production, use `#[cfg(not(dev))]` instead of `#[cfg(feature = "custom-protocol")]`. + +### Enhancements + +- [`9be314f0`](https://www.github.com/tauri-apps/tauri/commit/9be314f07a4ca5d14433d41919492f3e91b5536a)([#8951](https://www.github.com/tauri-apps/tauri/pull/8951)) Add plugins to `Cargo.toml` when using `tauri migrate` + +### Bug Fixes + +- [`cbd9755e`](https://www.github.com/tauri-apps/tauri/commit/cbd9755e0926a7e47e59deb50f4bb93d621791a5)([#8977](https://www.github.com/tauri-apps/tauri/pull/8977)) Fixes process logs not showing on `ios dev`. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.5` + +## \[2.0.0-beta.4] + +### Bug Fixes + +- [`e538ba58`](https://www.github.com/tauri-apps/tauri/commit/e538ba586c5b8b50955586c8ef2704adb5d7cc43)([#8949](https://www.github.com/tauri-apps/tauri/pull/8949)) Fixes android and iOS process spawning not working on Node.js. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.4` + +### Breaking Changes + +- [`a76fb118`](https://www.github.com/tauri-apps/tauri/commit/a76fb118ce2de22e1bdb4216bf0ac01dfc3e5799)([#8950](https://www.github.com/tauri-apps/tauri/pull/8950)) Changed the capability format to allow configuring both `remote: { urls: Vec }` and `local: bool (default: true)` instead of choosing one on the `context` field. + +## \[2.0.0-beta.3] + +### Enhancements + +- [`a029b9f7`](https://www.github.com/tauri-apps/tauri/commit/a029b9f77e432533a403c292940fa3efba68692c)([#8910](https://www.github.com/tauri-apps/tauri/pull/8910)) Setting up code signing is no longer required on iOS when using the simulator. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.3` + +## \[2.0.0-beta.2] + +### Enhancements + +- [`83a68deb`](https://www.github.com/tauri-apps/tauri/commit/83a68deb5676d39cd4728d2e140f6b46d5f787ed)([#8797](https://www.github.com/tauri-apps/tauri/pull/8797)) Update app template following capabilities configuration change. + +### Bug Fixes + +- [`aa06a053`](https://www.github.com/tauri-apps/tauri/commit/aa06a0534cf224038866e0ddd6910ea873b2574d)([#8810](https://www.github.com/tauri-apps/tauri/pull/8810)) Fix `tauri plugin android init` printing invalid code that has a missing closing `"`. +- [`3cee26a5`](https://www.github.com/tauri-apps/tauri/commit/3cee26a58ab44639a12c7816f4096655daa327a4)([#8865](https://www.github.com/tauri-apps/tauri/pull/8865)) On Windows, fixed `tauri info` fails to detect the build tool when the system language is CJK. +- [`052e8b43`](https://www.github.com/tauri-apps/tauri/commit/052e8b4311d9f0f963a2866163be27bfd8f70c60)([#8838](https://www.github.com/tauri-apps/tauri/pull/8838)) Downgrade minisign dependency fixing updater signing key bug and prevent it from happening in the future. +- [`fb0d9971`](https://www.github.com/tauri-apps/tauri/commit/fb0d997117367e3387896bcd0fba004579475c40)([#8783](https://www.github.com/tauri-apps/tauri/pull/8783)) Fixes a regression on the `--config` argument not accepting file paths. +- [`baca704d`](https://www.github.com/tauri-apps/tauri/commit/baca704d4b5fae239fc320d10140f35bd705bfbb)([#8768](https://www.github.com/tauri-apps/tauri/pull/8768)) Do not migrate updater configuration if the active flag is set to false. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.2` + +## \[2.0.0-beta.1] + +### Enhancements + +- [`4e101f80`](https://www.github.com/tauri-apps/tauri/commit/4e101f801657e7d01ce8c22f9c6468067d0caab2)([#8756](https://www.github.com/tauri-apps/tauri/pull/8756)) Moved the capability JSON schema to the `src-tauri/gen` folder so it's easier to track changes on the `capabilities` folder. +- [`4e101f80`](https://www.github.com/tauri-apps/tauri/commit/4e101f801657e7d01ce8c22f9c6468067d0caab2)([#8756](https://www.github.com/tauri-apps/tauri/pull/8756)) Update app and plugin templates following generated files change from tauri-build and tauri-plugin. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.1` + +## \[2.0.0-beta.0] + +### New Features + +- [`7fcc0bcd`](https://www.github.com/tauri-apps/tauri/commit/7fcc0bcd3482bbc8771e330942ef6cd78cc8ec35)([#8490](https://www.github.com/tauri-apps/tauri/pull/8490)) Add plugin initialization rust code when using `tauri add` +- [`1878766f`](https://www.github.com/tauri-apps/tauri/commit/1878766f7f81a03b0f0b87ec33ee113d7aa7a902)([#8667](https://www.github.com/tauri-apps/tauri/pull/8667)) Migrate the allowlist config to the new capability file format. + +### Enhancements + +- [`d6c7568c`](https://www.github.com/tauri-apps/tauri/commit/d6c7568c27445653edf570f3969163bc358ba2ba)([#8720](https://www.github.com/tauri-apps/tauri/pull/8720)) Add `files` option to the AppImage Configuration. +- [`b3209bb2`](https://www.github.com/tauri-apps/tauri/commit/b3209bb28bb379d5046d577c7e42319d6e76ced0)([#8688](https://www.github.com/tauri-apps/tauri/pull/8688)) Ignore global `.gitignore` when searching for tauri directory. +- [`e691208e`](https://www.github.com/tauri-apps/tauri/commit/e691208e7b39bb8e3ffc9bf66cff731a5025ef16)([#7837](https://www.github.com/tauri-apps/tauri/pull/7837)) Prevent unneeded double Cargo.toml rewrite on `dev` and `build`. +- [`f492efd7`](https://www.github.com/tauri-apps/tauri/commit/f492efd7144fdd8d25cac0c4d2389a95ab75fb02)([#8666](https://www.github.com/tauri-apps/tauri/pull/8666)) Update app and plugin template following the new access control permission model. + +### Bug Fixes + +- [`9cb9aa79`](https://www.github.com/tauri-apps/tauri/commit/9cb9aa7978f231f7da238b33d6ab33fdd2d2c842)([#8672](https://www.github.com/tauri-apps/tauri/pull/8672)) Allow license field in Cargo.toml to be `{ workspace = true }` + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-beta.0` + +### Breaking Changes + +- [`8de308d1`](https://www.github.com/tauri-apps/tauri/commit/8de308d1bf6a855d7a26af58bd0e744938ba47d8)([#8723](https://www.github.com/tauri-apps/tauri/pull/8723)) Restructured Tauri config per [RFC#5](https://github.com/tauri-apps/rfcs/blob/f3e82a6b0c5390401e855850d47dc7b7d9afd684/texts/0005-tauri-config-restructure.md): + + - Moved `package.productName`, `package.version` and `tauri.bundle.identifier` fields to the top-level. + - Removed `package` object. + - Renamed `tauri` object to `app`. + - Moved `tauri.bundle` object to the top-level. + - Renamed `build.distDir` field to `frontendDist`. + - Renamed `build.devPath` field to `devUrl` and will no longer accepts paths, it will only accept URLs. + - Moved `tauri.pattern` to `app.security.pattern`. + - Removed `tauri.bundle.updater` object, and its fields have been moved to the updater plugin under `plugins.updater` object. + - Moved `build.withGlobalTauri` to `app.withGlobalTauri`. + - Moved `tauri.bundle.dmg` object to `bundle.macOS.dmg`. + - Moved `tauri.bundle.deb` object to `bundle.linux.deb`. + - Moved `tauri.bundle.appimage` object to `bundle.linux.appimage`. + - Removed all license fields from each bundle configuration object and instead added `bundle.license` and `bundle.licenseFile`. + - Renamed `AppUrl` to `FrontendDist` and refactored its variants to be more explicit. + +## \[2.0.0-alpha.21] + +### New Features + +- [`27bad32d`](https://www.github.com/tauri-apps/tauri/commit/27bad32d4d4acca8155b20225d529d540fb9aaf4)([#7798](https://www.github.com/tauri-apps/tauri/pull/7798)) Add `files` object on the `tauri > bundle > macOS` configuration option. +- [`0ec28c39`](https://www.github.com/tauri-apps/tauri/commit/0ec28c39f478de7199a66dd75e8642e1aa1344e6)([#8529](https://www.github.com/tauri-apps/tauri/pull/8529)) Include tauri-build on the migration script. + +### Enhancements + +- [`091100ac`](https://www.github.com/tauri-apps/tauri/commit/091100acbb507b51de39fb1446f685926f888fd2)([#5202](https://www.github.com/tauri-apps/tauri/pull/5202)) Add RPM packaging + +### Bug Fixes + +- [`4f73057e`](https://www.github.com/tauri-apps/tauri/commit/4f73057e6fd4c137bc112367fb91f5fc0c8a39f6)([#8486](https://www.github.com/tauri-apps/tauri/pull/8486)) Prevent `Invalid target triple` warnings and correctly set `TAURI_ENV_` vars when target triple contains 4 components. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.21` + +### Breaking Changes + +- [`4f73057e`](https://www.github.com/tauri-apps/tauri/commit/4f73057e6fd4c137bc112367fb91f5fc0c8a39f6)([#8486](https://www.github.com/tauri-apps/tauri/pull/8486)) Removed `TAURI_ENV_PLATFORM_TYPE` which will not be set for CLI hook commands anymore, use `TAURI_ENV_PLATFORM` instead. Also Changed value of `TAURI_ENV_PLATFORM` and `TAURI_ENV_ARCH` values to match the target triple more accurately: + + - `darwin` and `androideabi` are no longer replaced with `macos` and `android` in `TAURI_ENV_PLATFORM`. + - `i686` and `i586` are no longer replaced with `x86` in `TAURI_ENV_ARCH`. + +## \[2.0.0-alpha.20] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.20` + +## \[2.0.0-alpha.19] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.19` + +## \[2.0.0-alpha.18] + +### New Features + +- [`50f7ccbb`](https://www.github.com/tauri-apps/tauri/commit/50f7ccbbf3467f33cc7dd1cca53125fec6eda1c6)([#6444](https://www.github.com/tauri-apps/tauri/pull/6444)) Add suport to SVG input image for the `tauri icon` command. +- [`25e5f91d`](https://www.github.com/tauri-apps/tauri/commit/25e5f91dae7fe2bbc1ba4317d5d829402bfd1d50)([#8200](https://www.github.com/tauri-apps/tauri/pull/8200)) Merge `src-tauri/Info.plist` and `src-tauri/Info.ios.plist` with the iOS project plist file. + +### Enhancements + +- [`01a7a983`](https://www.github.com/tauri-apps/tauri/commit/01a7a983aba2946b455a608b8a6a4b08cb25fc11)([#8128](https://www.github.com/tauri-apps/tauri/pull/8128)) Transform paths to relative to the mobile project for the IDE script runner script. + +### Bug Fixes + +- [`88dac86f`](https://www.github.com/tauri-apps/tauri/commit/88dac86f3b301d1919df6473a9e20f46b560f29b)([#8149](https://www.github.com/tauri-apps/tauri/pull/8149)) Ensure `tauri add` prints `rust_code` with plugin name in snake case. +- [`977d0e52`](https://www.github.com/tauri-apps/tauri/commit/977d0e52f14b1ad01c86371765ef25b36572459e)([#8202](https://www.github.com/tauri-apps/tauri/pull/8202)) Fixes `android build --open` and `ios build --open` IDE failing to read CLI options. +- [`bfbbefdb`](https://www.github.com/tauri-apps/tauri/commit/bfbbefdb9e13ed1f42f6db7fa9ceaa84db1267e9)([#8161](https://www.github.com/tauri-apps/tauri/pull/8161)) Fix invalid plugin template. +- [`92b50a3a`](https://www.github.com/tauri-apps/tauri/commit/92b50a3a398c9d55b6992a8f5c2571e4d72bdaaf)([#8209](https://www.github.com/tauri-apps/tauri/pull/8209)) Added support to Xcode's archive. This requires regenerating the Xcode project. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.18` + +## \[2.0.0-alpha.17] + +### Enhancements + +- [`c6c59cf2`](https://www.github.com/tauri-apps/tauri/commit/c6c59cf2373258b626b00a26f4de4331765dd487) Pull changes from Tauri 1.5 release. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.17` + +### Breaking Changes + +- [`198abe3c`](https://www.github.com/tauri-apps/tauri/commit/198abe3c2cae06dacab860b3a93f715dcf529a95)([#8076](https://www.github.com/tauri-apps/tauri/pull/8076)) Updated the mobile plugin templates following the tauri v2.0.0-alpha.17 changes. + +## \[2.0.0-alpha.16] + +### New Features + +- [`8b166e9b`](https://www.github.com/tauri-apps/tauri/commit/8b166e9bf82e69ddb3200a3a825614980bd8d433)([#7949](https://www.github.com/tauri-apps/tauri/pull/7949)) Add `--no-dev-server-wait` option to skip waiting for the dev server to start when using `tauri dev`. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.16` + +### Breaking Changes + +- [`8b166e9b`](https://www.github.com/tauri-apps/tauri/commit/8b166e9bf82e69ddb3200a3a825614980bd8d433)([#7949](https://www.github.com/tauri-apps/tauri/pull/7949)) Changed a number of environment variables used by tauri CLI for consistency and clarity: + + - `TAURI_PRIVATE_KEY` -> `TAURI_SIGNING_PRIVATE_KEY` + - `TAURI_KEY_PASSWORD` -> `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` + - `TAURI_SKIP_DEVSERVER_CHECK` -> `TAURI_CLI_NO_DEV_SERVER_WAIT` + - `TAURI_DEV_SERVER_PORT` -> `TAURI_CLI_PORT` + - `TAURI_PATH_DEPTH` -> `TAURI_CLI_CONFIG_DEPTH` + - `TAURI_FIPS_COMPLIANT` -> `TAURI_BUNDLER_WIX_FIPS_COMPLIANT` + - `TAURI_DEV_WATCHER_IGNORE_FILE` -> `TAURI_CLI_WATCHER_IGNORE_FILENAME` + - `TAURI_TRAY` -> `TAURI_LINUX_AYATANA_APPINDICATOR` + - `TAURI_APPLE_DEVELOPMENT_TEAM` -> `APPLE_DEVELOPMENT_TEAM` +- [`4caa1cca`](https://www.github.com/tauri-apps/tauri/commit/4caa1cca990806f2c2ef32d5dabaf56e82f349e6)([#7990](https://www.github.com/tauri-apps/tauri/pull/7990)) The `tauri plugin` subcommand is receving a couple of consitency and quality of life improvements: + + - Renamed `tauri plugin android/ios add` command to `tauri plugin android/ios init` to match the `tauri plugin init` command. + - Removed the `-n/--name` argument from the `tauri plugin init`, `tauri plugin android/ios init`, and is now parsed from the first positional argument. + - Added `tauri plugin new` to create a plugin in a new directory. + - Changed `tauri plugin init` to initalize a plugin in an existing directory (defaults to current directory) instead of creating a new one. + - Changed `tauri plugin init` to NOT generate mobile projects by default, you can opt-in to generate them using `--android` and `--ios` flags or `--mobile` flag or initalize them later using `tauri plugin android/ios init`. +- [`8b166e9b`](https://www.github.com/tauri-apps/tauri/commit/8b166e9bf82e69ddb3200a3a825614980bd8d433)([#7949](https://www.github.com/tauri-apps/tauri/pull/7949)) Removed checking for a new version of the CLI. +- [`ebcc21e4`](https://www.github.com/tauri-apps/tauri/commit/ebcc21e4b95f4e8c27639fb1bca545b432f52d5e)([#8057](https://www.github.com/tauri-apps/tauri/pull/8057)) Renamed the beforeDevCommand, beforeBuildCommand and beforeBundleCommand hooks environment variables from `TAURI_PLATFORM, TAURI_ARCH, TAURI_FAMILY, TAURI_PLATFORM_VERSION, TAURI_PLATFORM_TYPE and TAURI_DEBUG` to `TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG` to differentiate the prefix with other CLI environment variables. + +## \[2.0.0-alpha.15] + +### New Features + +- [`b2f17723`](https://www.github.com/tauri-apps/tauri/commit/b2f17723a415f04c2620132a6305eb138d7cb47f)([#7971](https://www.github.com/tauri-apps/tauri/pull/7971)) Use `devicectl` to connect to iOS 17+ devices on macOS 14+. + +### Bug Fixes + +- [`100d9ede`](https://www.github.com/tauri-apps/tauri/commit/100d9ede35995d9db21d2087dd5606adfafb89a5)([#7802](https://www.github.com/tauri-apps/tauri/pull/7802)) Properly read platform-specific configuration files for mobile targets. +- [`228e5a4c`](https://www.github.com/tauri-apps/tauri/commit/228e5a4c76ad5f97409c912d07699b49ba4bb162)([#7902](https://www.github.com/tauri-apps/tauri/pull/7902)) Fixes `icon` command not writing files to the correct Android project folders. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.15` + +## \[2.0.0-alpha.14] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.14` + +### Breaking Changes + +- [`d5074af5`](https://www.github.com/tauri-apps/tauri/commit/d5074af562b2b5cb6c5711442097c4058af32db6)([#7801](https://www.github.com/tauri-apps/tauri/pull/7801)) The custom protocol on Android now uses the `http` scheme instead of `https`. + +## \[2.0.0-alpha.13] + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.13` + +### Breaking Changes + +- [`4cb51a2d`](https://www.github.com/tauri-apps/tauri/commit/4cb51a2d56cfcae0749062c79ede5236bd8c02c2)([#7779](https://www.github.com/tauri-apps/tauri/pull/7779)) The custom protocol on Windows now uses the `http` scheme instead of `https`. +- [`974e38b4`](https://www.github.com/tauri-apps/tauri/commit/974e38b4ddc198530aa977ec77d513b76013b9f3)([#7744](https://www.github.com/tauri-apps/tauri/pull/7744)) Renamed the `plugin add` command to `add`. + +## \[2.0.0-alpha.12] + +### Bug Fixes + +- [`b75a1210`](https://www.github.com/tauri-apps/tauri/commit/b75a1210bed589187678861d7314ae6279bf7c87)([#7762](https://www.github.com/tauri-apps/tauri/pull/7762)) Fixes a regression on alpha.11 where iOS logs aren't being displayed when using `ios dev` with a real device. +- [`8faa5a4a`](https://www.github.com/tauri-apps/tauri/commit/8faa5a4a1238a44ca7b54d2084aaed553ac2a1ba)([#7765](https://www.github.com/tauri-apps/tauri/pull/7765)) Ensure asset directory exists on the iOS project. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.12` + +## \[2.0.0-alpha.11] + +### New Features + +- [`522de0e7`](https://www.github.com/tauri-apps/tauri/commit/522de0e78891d0bdf6387a5118985fc41a11baeb)([#7447](https://www.github.com/tauri-apps/tauri/pull/7447)) Expose an environment variable `TAURI_${PLUGIN_NAME}_PLUGIN_CONFIG` for each defined plugin configuration object. +- [`c7dacca4`](https://www.github.com/tauri-apps/tauri/commit/c7dacca4661c6ddf937c1a3dd3ace896d5baf40c)([#7446](https://www.github.com/tauri-apps/tauri/pull/7446)) Expose the `TAURI_IOS_PROJECT_PATH` and `TAURI_IOS_APP_NAME` environment variables when using `ios` commands. +- [`aa94f719`](https://www.github.com/tauri-apps/tauri/commit/aa94f7197e4345a7cab1617272b10895859674f9)([#7445](https://www.github.com/tauri-apps/tauri/pull/7445)) Generate empty entitlements file for the iOS project. +- [`d010bc07`](https://www.github.com/tauri-apps/tauri/commit/d010bc07b81116bef769b64cdc19b23dff762d48)([#7554](https://www.github.com/tauri-apps/tauri/pull/7554)) Set the iOS project PRODUCT_NAME value to the string under `tauri.conf.json > package > productName` if it is set. +- [`8af24974`](https://www.github.com/tauri-apps/tauri/commit/8af2497496f11ee481472dfdc3125757346c1a3e)([#7561](https://www.github.com/tauri-apps/tauri/pull/7561)) The `migrate` command now automatically reads all JavaScript files and updates `@tauri-apps/api` import paths and install the missing plugins. + +### Enhancements + +- [`fbeb5b91`](https://www.github.com/tauri-apps/tauri/commit/fbeb5b9185baeda19e865228179e3e44c165f1d9)([#7170](https://www.github.com/tauri-apps/tauri/pull/7170)) Update migrate command to update the configuration CSP to include `ipc:` on the `connect-src` directive, needed by the new IPC using custom protocols. + +### Dependencies + +- Upgraded to `tauri-cli@2.0.0-alpha.11` + +## \[2.0.0-alpha.10] + +### New Features + +- [`7e5905ae`](https://www.github.com/tauri-apps/tauri/commit/7e5905ae1d56b920de0e821be28036cbbe302518)([#7023](https://www.github.com/tauri-apps/tauri/pull/7023)) Added `tauri plugin add` command to add a plugin to the Tauri project. +- [`b0f94775`](https://www.github.com/tauri-apps/tauri/commit/b0f947752a315b7b89c5979de50157f997f1dd6e)([#7008](https://www.github.com/tauri-apps/tauri/pull/7008)) Added `migrate` command. + +### Enhancements + +- [`aa6c9164`](https://www.github.com/tauri-apps/tauri/commit/aa6c9164e63b5316d690f25b1c118f1b12310570)([#7007](https://www.github.com/tauri-apps/tauri/pull/7007)) Don't build library files when building desktop targets. +- [`a28fdf7e`](https://www.github.com/tauri-apps/tauri/commit/a28fdf7ec71bf6db2498569004de83318b6d25ac)([#7044](https://www.github.com/tauri-apps/tauri/pull/7044)) Skip Rust target installation if they are already installed. +- [`735db1ce`](https://www.github.com/tauri-apps/tauri/commit/735db1ce839a16ba998c9e6786c441e3bf6c90b3)([#7044](https://www.github.com/tauri-apps/tauri/pull/7044)) Add `--skip-targets-install` flag for `tauri android init` and `tauri ios init` to skip installing needed rust targets vie rustup. + +### Bug Fixes + +- [`1ed2600d`](https://www.github.com/tauri-apps/tauri/commit/1ed2600da67715908af857255305eaeb293d8791)([#6771](https://www.github.com/tauri-apps/tauri/pull/6771)) Set current directory to tauri directory before reading config file. +- [`4847b87b`](https://www.github.com/tauri-apps/tauri/commit/4847b87b1067dd8c6e73986059f51e6eee1f1121)([#7209](https://www.github.com/tauri-apps/tauri/pull/7209)) Fix `tauri (android|ios) (dev|build)` failing when using `npx tauri` +- [`655c714e`](https://www.github.com/tauri-apps/tauri/commit/655c714e4100f69d4265c5ea3f08f5bc11709446)([#7240](https://www.github.com/tauri-apps/tauri/pull/7240)) Fixes panic when exiting the `ios dev` command with Ctrl + C. +- [`6252380f`](https://www.github.com/tauri-apps/tauri/commit/6252380f4447c66913b0f06611e5949005b1eec2)([#7241](https://www.github.com/tauri-apps/tauri/pull/7241)) Exit `beforeDevCommand` process if the android or iOS `dev` command fails. + +## \[2.0.0-alpha.9] + +- [`19cd0e49`](https://www.github.com/tauri-apps/tauri/commit/19cd0e49603ad3500cd2180bfa16e1649e3a771a)([#6811](https://www.github.com/tauri-apps/tauri/pull/6811)) Add `key.properties` file to android's `.gitignore`. +- [`124d5c5a`](https://www.github.com/tauri-apps/tauri/commit/124d5c5adf67f0b68d2e41c7ddb07d9cb63f1996)([#6788](https://www.github.com/tauri-apps/tauri/pull/6788)) On mobile, fix regression introduced in `tauri-cli` version `2.0.0-alpha.3` where library not found error was thrown. +- [`31444ac1`](https://www.github.com/tauri-apps/tauri/commit/31444ac196add770f2ad18012d7c18bce7538f22)([#6725](https://www.github.com/tauri-apps/tauri/pull/6725)) Update mobile template to `wry@0.28` +- [`41f49aea`](https://www.github.com/tauri-apps/tauri/commit/41f49aeae646f2cb70b42002bb1371c79e592243)([#6659](https://www.github.com/tauri-apps/tauri/pull/6659)) Update tauri-mobile to fix running ADB scripts. +- [`6d1fa49f`](https://www.github.com/tauri-apps/tauri/commit/6d1fa49fce3a03965ce7c656390e682ce5b776e3)([#6881](https://www.github.com/tauri-apps/tauri/pull/6881)) Clear Android plugin JSON file before building Rust library to ensure removed plugins are propagated to the Android project. +- [`5a9307d1`](https://www.github.com/tauri-apps/tauri/commit/5a9307d11c1643221bc2a280feb00024f8fa6030)([#6890](https://www.github.com/tauri-apps/tauri/pull/6890)) Update android template to gradle 8.0 +- [`73c803a5`](https://www.github.com/tauri-apps/tauri/commit/73c803a561181137f20366f5d52511392a619f2b)([#6837](https://www.github.com/tauri-apps/tauri/pull/6837)) Inject Tauri configuration in the Android assets. +- [`e1e85dc2`](https://www.github.com/tauri-apps/tauri/commit/e1e85dc2a5f656fc37867e278cae8042037740ac)([#6925](https://www.github.com/tauri-apps/tauri/pull/6925)) Moved the updater configuration to the `BundleConfig`. +- [`d48aaa15`](https://www.github.com/tauri-apps/tauri/commit/d48aaa150a1ceeb65ec0ba18f1e3795f70c838e3)([#6894](https://www.github.com/tauri-apps/tauri/pull/6894)) Add Cargo manifest files for the plugin example templates. +- [`e1e85dc2`](https://www.github.com/tauri-apps/tauri/commit/e1e85dc2a5f656fc37867e278cae8042037740ac)([#6925](https://www.github.com/tauri-apps/tauri/pull/6925)) Removed the allowlist configuration. + +## \[2.0.0-alpha.8] + +- Do not gitignore the Android project's `buildSrc` folder by default since we removed absolute paths from it. + - [ee2d3b97](https://www.github.com/tauri-apps/tauri/commit/ee2d3b971df6d3630b8d935394fb4febcfa3a909) fix(cli): remove buildSrc from Android project gitignored paths ([#6702](https://www.github.com/tauri-apps/tauri/pull/6702)) on 2023-04-13 +- Fixes iOS build script using the wrong path for the app library file. + - [abc5f91f](https://www.github.com/tauri-apps/tauri/commit/abc5f91fa3569efc9dfdee46d1c501eda8755944) fix(cli): iOS Xcode script using incorrect library path ([#6699](https://www.github.com/tauri-apps/tauri/pull/6699)) on 2023-04-13 + +## \[2.0.0-alpha.7] + +- Add `--release` flag for `tauri android dev` however you will need to sign your Android app, see https://next--tauri.netlify.app/next/guides/distribution/sign-android + - [63f088e5](https://www.github.com/tauri-apps/tauri/commit/63f088e5fc9701fd7fb329dad7ffb27a2d8fd5aa) feat(cli): add `--release` for `android dev` ([#6638](https://www.github.com/tauri-apps/tauri/pull/6638)) on 2023-04-05 +- Build only specified rust targets for `tauri android build` instead of all. + - [d03e47d1](https://www.github.com/tauri-apps/tauri/commit/d03e47d141c3917520975be9081775dbc4e9d4fd) fix: only build specified rust targets for aab/apk build ([#6625](https://www.github.com/tauri-apps/tauri/pull/6625)) on 2023-04-05 +- Use local ip address for built-in dev server on mobile. + - [7fec0f08](https://www.github.com/tauri-apps/tauri/commit/7fec0f083c932dc63ccb8716080d97e2ab985b25) fix(cli): use local ip addr for built-in server on mobile, closes [#6454](https://www.github.com/tauri-apps/tauri/pull/6454) ([#6631](https://www.github.com/tauri-apps/tauri/pull/6631)) on 2023-04-04 +- Readd the Cargo.toml file to the plugin template. + - [5288a386](https://www.github.com/tauri-apps/tauri/commit/5288a386f1bf8ac11f991350463c3f5c20983f43) fix(cli): readd Cargo.toml to the plugin template ([#6637](https://www.github.com/tauri-apps/tauri/pull/6637)) on 2023-04-04 + +## \[2.0.0-alpha.6] + +- Use Ubuntu 20.04 to compile the CLI, increasing the minimum libc version required. +- Automatically enable the `rustls-tls` tauri feature on mobile and `native-tls` on desktop if `rustls-tls` is not enabled. + - [cfdee00f](https://www.github.com/tauri-apps/tauri/commit/cfdee00f2b1455a9719bc44823fdaeabbe4c1cb2) refactor(core): fix tls features, use rustls on mobile ([#6591](https://www.github.com/tauri-apps/tauri/pull/6591)) on 2023-03-30 + +## \[2.0.0-alpha.5] + +- Fixes the iOS project script to build the Rust library. + - [6e3e4c22](https://www.github.com/tauri-apps/tauri/commit/6e3e4c22be51500bec7856d90dcb2e40ef7fe1b4) fix(cli): use correct variable on script to build Rust iOS code ([#6581](https://www.github.com/tauri-apps/tauri/pull/6581)) on 2023-03-29 +- Fix `tauri android build/dev` crashing when used with standalone `pnpm` executable on Windows. + - [39df2c98](https://www.github.com/tauri-apps/tauri/commit/39df2c982e5e2ee8617b40f829a2f2e4abfce412) fix(cli/android): fallback to `${program}.cmd` ([#6576](https://www.github.com/tauri-apps/tauri/pull/6576)) on 2023-03-29 + - [6b469c40](https://www.github.com/tauri-apps/tauri/commit/6b469c40c6244ba773d7478adbb41db6fdc72822) chore(changes): adjust change file for Android script execution fix on 2023-03-29 + +## \[2.0.0-alpha.4] + +- Fix android project build crashing when using `pnpm` caused by extra `--`. + - [c787f749](https://www.github.com/tauri-apps/tauri/commit/c787f749de01b79d891615aad8c37b23037fff4c) fix(cli): only add `--` to generated android template for npm ([#6508](https://www.github.com/tauri-apps/tauri/pull/6508)) on 2023-03-21 +- Fixes the Android build gradle plugin implementation on Windows. + - [00241fa9](https://www.github.com/tauri-apps/tauri/commit/00241fa92d104870068a701519340633cc35b716) fix(cli): append .cmd on the gradle plugin binary on Windows, fix [#6502](https://www.github.com/tauri-apps/tauri/pull/6502) ([#6503](https://www.github.com/tauri-apps/tauri/pull/6503)) on 2023-03-21 +- Update `napi-rs` dependencies to latest to fix CLI hanging up forever. + - [d5ac76b5](https://www.github.com/tauri-apps/tauri/commit/d5ac76b53c7f35253db84ddfbf4ecf975ff6307d) chore(deps): update napi-rs, closes [#6502](https://www.github.com/tauri-apps/tauri/pull/6502) ([#6513](https://www.github.com/tauri-apps/tauri/pull/6513)) on 2023-03-21 + +## \[2.0.0-alpha.3] + +- Added `plugin android add` and `plugin ios add` commands to add mobile plugin functionality to existing projects. + - [14d03d42](https://www.github.com/tauri-apps/tauri/commit/14d03d426e86d966950a790926c04560c76203b3) refactor(cli): enhance plugin commands for mobile ([#6289](https://www.github.com/tauri-apps/tauri/pull/6289)) on 2023-02-16 +- Add commands to add native Android and iOS functionality to plugins. + - [05dad087](https://www.github.com/tauri-apps/tauri/commit/05dad0876842e2a7334431247d49365cee835d3e) feat: initial work for iOS plugins ([#6205](https://www.github.com/tauri-apps/tauri/pull/6205)) on 2023-02-11 +- Use temp file instead of environment variable to pass CLI IPC websocket address to the IDE. + - [894a8d06](https://www.github.com/tauri-apps/tauri/commit/894a8d060c12a482a0fc5b3714f3848189b809de) refactor(cli): use temp file to communicate IPC websocket address ([#6219](https://www.github.com/tauri-apps/tauri/pull/6219)) on 2023-02-08 +- Change the Android template to enable minification on release and pull ProGuard rules from proguard-tauri.pro. + - [bef4ef51](https://www.github.com/tauri-apps/tauri/commit/bef4ef51bc2c633b88db121c2087a38dddb7d6bf) feat(android): enable minify on release, add proguard rules ([#6257](https://www.github.com/tauri-apps/tauri/pull/6257)) on 2023-02-13 +- Print an error if the Android project was generated with an older bundle identifier or package name. + - [79eb0542](https://www.github.com/tauri-apps/tauri/commit/79eb054292b04bb089a0e4df401a5986b33b691e) feat(cli): handle Android package identifier change ([#6314](https://www.github.com/tauri-apps/tauri/pull/6314)) on 2023-02-19 +- Fixes the generated mobile build script when using an NPM runner. + - [62f15265](https://www.github.com/tauri-apps/tauri/commit/62f152659204ce1218178596f463f0bcfbd4e6dc) fix(cli): generate build script using NPM runner if it was used ([#6233](https://www.github.com/tauri-apps/tauri/pull/6233)) on 2023-02-10 +- Resolve Android package name from single word bundle identifiers. + - [60a8b07d](https://www.github.com/tauri-apps/tauri/commit/60a8b07dc7c56c9c45331cb57d9afb410e7eadf3) fix: handle single word bundle identifier when resolving Android domain ([#6313](https://www.github.com/tauri-apps/tauri/pull/6313)) on 2023-02-19 +- Update Android project template with fix to crash on orientation change. + - [947eb391](https://www.github.com/tauri-apps/tauri/commit/947eb391ca41cebdb11abd9ffaec642baffbf44a) fix(android): crash on orientation change due to activity recreation ([#6261](https://www.github.com/tauri-apps/tauri/pull/6261)) on 2023-02-13 +- Added `--ios-color` option to the `tauri icon` command. + - [67755425](https://www.github.com/tauri-apps/tauri/commit/677554257e40e05b1af0dd61c982d6be8a8a033c) feat(cli): add `--ios-color` option to set iOS icon background color ([#6247](https://www.github.com/tauri-apps/tauri/pull/6247)) on 2023-02-12 +- Fixes HMR on mobile when devPath is configured to load a filesystem path. + - [4a82da29](https://www.github.com/tauri-apps/tauri/commit/4a82da2919e0564ec993b2005dc65b5b49407b36) fix(cli): use local ip address for reload ([#6285](https://www.github.com/tauri-apps/tauri/pull/6285)) on 2023-02-16 +- Ignore the `gen` folder on the dev watcher. + - [cab4ff95](https://www.github.com/tauri-apps/tauri/commit/cab4ff95b98aeac88401c1fed2d8b8940e4180cb) fix(cli): ignore the `gen` folder on the dev watcher ([#6232](https://www.github.com/tauri-apps/tauri/pull/6232)) on 2023-02-09 +- Correctly pass arguments from `npm run` to `tauri`. + - [1b343bd1](https://www.github.com/tauri-apps/tauri/commit/1b343bd11686f47f24a87298d8192097c66250f6) fix(cli): use `npm run tauri -- foo` for correctly passing args to tauri ([#6448](https://www.github.com/tauri-apps/tauri/pull/6448)) on 2023-03-16 +- Changed the `--api` flag on `plugin init` to `--no-api`. + - [14d03d42](https://www.github.com/tauri-apps/tauri/commit/14d03d426e86d966950a790926c04560c76203b3) refactor(cli): enhance plugin commands for mobile ([#6289](https://www.github.com/tauri-apps/tauri/pull/6289)) on 2023-02-16 + +## \[2.0.0-alpha.2] + +- Fixes `TAURI_*` environment variables for hook scripts on mobile commands. + - [1af9be90](https://www.github.com/tauri-apps/tauri/commit/1af9be904a309138b9f79dc741391000b1652c75) feat(cli): properly fill target for TAURI\_ env vars on mobile ([#6116](https://www.github.com/tauri-apps/tauri/pull/6116)) on 2023-01-23 +- Force colored logs on mobile commands. + - [2c4a0bbd](https://www.github.com/tauri-apps/tauri/commit/2c4a0bbd1fbe15d7500264e6490772397e1917ed) feat(cli): force colored logs on mobile commands ([#5934](https://www.github.com/tauri-apps/tauri/pull/5934)) on 2022-12-28 +- Keep the process alive even when the iOS application is closed. + - [dee9460f](https://www.github.com/tauri-apps/tauri/commit/dee9460f9c9bc92e9c638e7691e616849ac2085b) feat: keep CLI alive when iOS app exits, show logs, closes [#5855](https://www.github.com/tauri-apps/tauri/pull/5855) ([#5902](https://www.github.com/tauri-apps/tauri/pull/5902)) on 2022-12-27 +- Show all application logs on iOS. + - [dee9460f](https://www.github.com/tauri-apps/tauri/commit/dee9460f9c9bc92e9c638e7691e616849ac2085b) feat: keep CLI alive when iOS app exits, show logs, closes [#5855](https://www.github.com/tauri-apps/tauri/pull/5855) ([#5902](https://www.github.com/tauri-apps/tauri/pull/5902)) on 2022-12-27 +- Print log output for all tags on Android development. + - [8cc11149](https://www.github.com/tauri-apps/tauri/commit/8cc111494d74161e489152e52191e1442dd99759) fix(cli): print Android logs for all tags on 2023-01-17 +- Add support to custom and kebab case library names for mobile apps. + - [50f6dd87](https://www.github.com/tauri-apps/tauri/commit/50f6dd87b1ac2c99f8794b055f1acba4ef7d34d3) feat: improvements to support hyphens in crate name ([#5989](https://www.github.com/tauri-apps/tauri/pull/5989)) on 2023-01-06 +- Fix target directory detection when compiling for Android. + - [e873bae0](https://www.github.com/tauri-apps/tauri/commit/e873bae09f0f27517f720a753f51c1dcb903f883) fix(cli): Cargo target dir detection on Android, closes [#5865](https://www.github.com/tauri-apps/tauri/pull/5865) ([#5932](https://www.github.com/tauri-apps/tauri/pull/5932)) on 2022-12-28 + +## \[2.0.0-alpha.1] + +- Fixes running on device using Xcode 14. + - [1e4a6758](https://www.github.com/tauri-apps/tauri/commit/1e4a675843c486bddc11292d09fb766e98758514) fix(cli): run on iOS device on Xcode 14 ([#5807](https://www.github.com/tauri-apps/tauri/pull/5807)) on 2022-12-12 +- Improve local IP address detection with user selection. + - [76204b89](https://www.github.com/tauri-apps/tauri/commit/76204b893846a04552f8f8b87ad2c9b55e1b417f) feat(cli): improve local IP detection ([#5817](https://www.github.com/tauri-apps/tauri/pull/5817)) on 2022-12-12 + +## \[2.0.0-alpha.0] + +- Added `android build` command. + - [4c9ea450](https://www.github.com/tauri-apps/tauri/commit/4c9ea450c3b47c6b8c825ba32e9837909945ccd7) feat(cli): add `android build` command ([#4999](https://www.github.com/tauri-apps/tauri/pull/4999)) on 2022-08-22 +- Added `ios build` command. + - [403859d4](https://www.github.com/tauri-apps/tauri/commit/403859d47e1a9bf978b353fa58e4b971e66337a3) feat(cli): add `ios build` command ([#5002](https://www.github.com/tauri-apps/tauri/pull/5002)) on 2022-08-22 +- Added `android dev` and `ios dev` commands. + - [6f061504](https://www.github.com/tauri-apps/tauri/commit/6f0615044d09ec58393a7ebca5e45bb175e20db3) feat(cli): add `android dev` and `ios dev` commands ([#4982](https://www.github.com/tauri-apps/tauri/pull/4982)) on 2022-08-20 +- Added `android init` and `ios init` commands. + - [d44f67f7](https://www.github.com/tauri-apps/tauri/commit/d44f67f7afd30a81d53a973ec603b2a253150bde) feat: add `android init` and `ios init` commands ([#4942](https://www.github.com/tauri-apps/tauri/pull/4942)) on 2022-08-15 +- Added `android open` and `ios open` commands. + - [a9c8e565](https://www.github.com/tauri-apps/tauri/commit/a9c8e565c6495961940877df7090f307be16b554) feat: add `android open` and `ios open` commands ([#4946](https://www.github.com/tauri-apps/tauri/pull/4946)) on 2022-08-15 +- First mobile alpha release! + - [fa3a1098](https://www.github.com/tauri-apps/tauri/commit/fa3a10988a03aed1b66fb17d893b1a9adb90f7cd) feat(ci): prepare 2.0.0-alpha.0 ([#5786](https://www.github.com/tauri-apps/tauri/pull/5786)) on 2022-12-08 + +## \[1.5.11] + +### Bug Fixes + +- [`b15948b11`](https://www.github.com/tauri-apps/tauri/commit/b15948b11c0e362eea7ef57a4606f15f7dbd886b)([#8903](https://www.github.com/tauri-apps/tauri/pull/8903)) Fix `.taurignore` failing to ignore in some cases. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.11` + +## \[1.5.10] + +### Bug Fixes + +- [`b0f27814`](https://www.github.com/tauri-apps/tauri/commit/b0f27814b90ded2f1ed44b7852080eedbff0d9e4)([#8776](https://www.github.com/tauri-apps/tauri/pull/8776)) Fix `fail to rename app` when using `--profile dev`. +- [`0bff8c32`](https://www.github.com/tauri-apps/tauri/commit/0bff8c325d004fdead2023f58e0f5fd73a9c22ba)([#8697](https://www.github.com/tauri-apps/tauri/pull/8697)) Fix the built-in dev server failing to serve files when URL had queries `?` and other url components. +- [`67d7877f`](https://www.github.com/tauri-apps/tauri/commit/67d7877f27f265c133a70d48a46c83ffff31d571)([#8520](https://www.github.com/tauri-apps/tauri/pull/8520)) The cli now also watches cargo workspace members if the tauri folder is the workspace root. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.10` + +## \[1.5.9] + +### Bug Fixes + +- [`0a2175ea`](https://www.github.com/tauri-apps/tauri/commit/0a2175eabb736b2a4cd01ab682e08be0b5ebb2b9)([#8439](https://www.github.com/tauri-apps/tauri/pull/8439)) Expand glob patterns in workspace member paths so the CLI would watch all matching pathhs. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.9` + +## \[1.5.8] + +### Dependencies + +- Upgraded to `tauri-cli@1.5.8` + +## \[1.5.7] + +### Bug Fixes + +- [`1d5aa38a`](https://www.github.com/tauri-apps/tauri/commit/1d5aa38ae418ea31f593590b6d32cf04d3bfd8c1)([#8162](https://www.github.com/tauri-apps/tauri/pull/8162)) Fixes errors on command output, occuring when the output stream contains an invalid UTF-8 character, or ends with a multi-bytes UTF-8 character. +- [`f26d9f08`](https://www.github.com/tauri-apps/tauri/commit/f26d9f0884f63f61b9f4d4fac15e6b251163793e)([#8263](https://www.github.com/tauri-apps/tauri/pull/8263)) Fixes an issue in the NSIS installer which caused the uninstallation to leave empty folders on the system if the `resources` feature was used. +- [`92bc7d0e`](https://www.github.com/tauri-apps/tauri/commit/92bc7d0e16157434330a1bcf1eefda6f0f1e5f85)([#8233](https://www.github.com/tauri-apps/tauri/pull/8233)) Fixes an issue in the NSIS installer which caused the installation to take much longer than expected when many `resources` were added to the bundle. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.7` + +## \[1.5.6] + +### Bug Fixes + +- [`5264e41d`](https://www.github.com/tauri-apps/tauri/commit/5264e41db3763e4c2eb0c3c21bd423fb7bece3e2)([#8082](https://www.github.com/tauri-apps/tauri/pull/8082)) Downgraded `rust-minisign` to `0.7.3` to fix signing updater bundles with empty passwords. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.6` + +## \[1.5.5] + +### Enhancements + +- [`9bead42d`](https://www.github.com/tauri-apps/tauri/commit/9bead42dbca0fb6dd7ea0b6bfb2f2308a5c5f992)([#8059](https://www.github.com/tauri-apps/tauri/pull/8059)) Allow rotating the updater private key. + +### Bug Fixes + +- [`be8e5aa3`](https://www.github.com/tauri-apps/tauri/commit/be8e5aa3071d9bc5d0bd24647e8168f312d11c8d)([#8042](https://www.github.com/tauri-apps/tauri/pull/8042)) Fixes duplicated newlines on command outputs. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.5` + +## \[1.5.4] + +### Dependencies + +- Upgraded to `tauri-cli@1.5.4` + +## \[1.5.3] + +### Dependencies + +- Upgraded to `tauri-cli@1.5.3` + +## \[1.5.2] + +### Dependencies + +- Upgraded to `tauri-cli@1.5.2` + +## \[1.5.1] + +### Bug Fixes + +- [`d6eb46cf`](https://www.github.com/tauri-apps/tauri/commit/d6eb46cf1116d147121f6b6db9d390b5e2fb238d)([#7934](https://www.github.com/tauri-apps/tauri/pull/7934)) On macOS, fix the `apple-id` option name when using `notarytools submit`. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.1` + +## \[1.5.0] + +### New Features + +- [`e1526626`](https://www.github.com/tauri-apps/tauri/commit/e152662687ece7a62d383923a50751cc0dd34331)([#7723](https://www.github.com/tauri-apps/tauri/pull/7723)) Support Bun package manager in CLI + +### Enhancements + +- [`13279917`](https://www.github.com/tauri-apps/tauri/commit/13279917d4cae071d0ce3a686184d48af079f58a)([#7713](https://www.github.com/tauri-apps/tauri/pull/7713)) Add version of Rust Tauri CLI installed with Cargo to `tauri info` command. + +### Bug Fixes + +- [`dad4f54e`](https://www.github.com/tauri-apps/tauri/commit/dad4f54eec9773d2ea6233a7d9fd218741173823)([#7277](https://www.github.com/tauri-apps/tauri/pull/7277)) Removed the automatic version check of the CLI that ran after `tauri` commands which caused various issues. + +### Dependencies + +- Upgraded to `tauri-cli@1.5.0` + +## \[1.4.0] + +### New Features + +- [`0ddbb3a1`](https://www.github.com/tauri-apps/tauri/commit/0ddbb3a1dc1961ba5c6c1a60081513c1380c8af1)([#7015](https://www.github.com/tauri-apps/tauri/pull/7015)) Provide prebuilt CLIs for Windows ARM64 targets. +- [`35cd751a`](https://www.github.com/tauri-apps/tauri/commit/35cd751adc6fef1f792696fa0cfb471b0bf99374)([#5176](https://www.github.com/tauri-apps/tauri/pull/5176)) Added the `desktop_template` option on `tauri.conf.json > tauri > bundle > deb`. +- [`6c5ade08`](https://www.github.com/tauri-apps/tauri/commit/6c5ade08d97844bb685789d30e589400bbe3e04c)([#4537](https://www.github.com/tauri-apps/tauri/pull/4537)) Added `tauri completions` to generate shell completions scripts. +- [`e092f799`](https://www.github.com/tauri-apps/tauri/commit/e092f799469ff32c7d1595d0f07d06fd2dab5c29)([#6887](https://www.github.com/tauri-apps/tauri/pull/6887)) Add `nsis > template` option to specify custom NSIS installer template. + +### Enhancements + +- [`d75c1b82`](https://www.github.com/tauri-apps/tauri/commit/d75c1b829bd96d9e3a672bcc79120597d5ada4a0)([#7181](https://www.github.com/tauri-apps/tauri/pull/7181)) Print a useful error when `updater` bundle target is specified without an updater-enabled target. +- [`52474e47`](https://www.github.com/tauri-apps/tauri/commit/52474e479d695865299d8c8d868fb98b99731020)([#7141](https://www.github.com/tauri-apps/tauri/pull/7141)) Enhance injection of Cargo features. +- [`2659ca1a`](https://www.github.com/tauri-apps/tauri/commit/2659ca1ab4799a5bda65c229c149e98bd01eb1ee)([#6900](https://www.github.com/tauri-apps/tauri/pull/6900)) Add `rustls` as default Cargo feature. + +### Bug Fixes + +- [`3cb7a3e6`](https://www.github.com/tauri-apps/tauri/commit/3cb7a3e642bb10ee90dc1d24daa48b8c8c15c9ce)([#6997](https://www.github.com/tauri-apps/tauri/pull/6997)) Fix built-in devserver adding hot-reload code to non-html files. +- [`fb7ef8da`](https://www.github.com/tauri-apps/tauri/commit/fb7ef8dacd9ade96976c84d22507782cdaf38acf)([#6667](https://www.github.com/tauri-apps/tauri/pull/6667)) Fix nodejs binary regex when `0` is in the version name, for example `node-20` +- [`1253bbf7`](https://www.github.com/tauri-apps/tauri/commit/1253bbf7ae11a87887e0b3bd98cc26dbb98c8130)([#7013](https://www.github.com/tauri-apps/tauri/pull/7013)) Fixes Cargo.toml feature rewriting. + +## \[1.3.1] + +- Correctly escape XML for resource files in WiX bundler. + - Bumped due to a bump in tauri-bundler. + - Bumped due to a bump in cli.rs. + - [6a6b1388](https://www.github.com/tauri-apps/tauri/commit/6a6b1388ea5787aea4c0e0b0701a4772087bbc0f) fix(bundler): correctly escape resource xml, fixes [#6853](https://www.github.com/tauri-apps/tauri/pull/6853) ([#6855](https://www.github.com/tauri-apps/tauri/pull/6855)) on 2023-05-04 + +- Added the following languages to the NSIS bundler: + +- `Spanish` + +- `SpanishInternational` + +- Bumped due to a bump in tauri-bundler. + - Bumped due to a bump in cli.rs. + +- [422b4817](https://www.github.com/tauri-apps/tauri/commit/422b48179856504e980a156500afa8e22c44d357) Add Spanish and SpanishInternational languages ([#6871](https://www.github.com/tauri-apps/tauri/pull/6871)) on 2023-05-06 + +- Correctly escape arguments in NSIS script to fix bundling apps that use non-default WebView2 install modes. + - Bumped due to a bump in tauri-bundler. + - Bumped due to a bump in cli.rs. + - [2915bd06](https://www.github.com/tauri-apps/tauri/commit/2915bd068ed40dc01a363b69212c6b6f2d3ec01e) fix(bundler): Fix webview install modes in NSIS bundler ([#6854](https://www.github.com/tauri-apps/tauri/pull/6854)) on 2023-05-04 + +## \[1.3.0] + +- Add `--ci` flag and respect the `CI` environment variable on the `signer generate` command. In this case the default password will be an empty string and the CLI will not prompt for a value. + - [8fb1df8a](https://www.github.com/tauri-apps/tauri/commit/8fb1df8aa65a52cdb4a7e1bb9dda9b912a7a2895) feat(cli): add `--ci` flag to `signer generate`, closes [#6089](https://www.github.com/tauri-apps/tauri/pull/6089) ([#6097](https://www.github.com/tauri-apps/tauri/pull/6097)) on 2023-01-19 +- Fix Outdated Github Actions in the Plugin Templates `with-api` and `backend` + - [a926b49a](https://www.github.com/tauri-apps/tauri/commit/a926b49a01925ca757d391994bfac3beea29599b) Fix Github Actions of Tauri Plugin with-api template ([#6603](https://www.github.com/tauri-apps/tauri/pull/6603)) on 2023-04-03 +- Do not crash on Cargo.toml watcher. + - [e8014a7f](https://www.github.com/tauri-apps/tauri/commit/e8014a7f612a1094461ddad63aacc498a2682ff5) fix(cli): do not crash on watcher ([#6303](https://www.github.com/tauri-apps/tauri/pull/6303)) on 2023-02-17 +- Fix crash when nodejs binary has the version in its name, for example `node-18` + - [1c8229fb](https://www.github.com/tauri-apps/tauri/commit/1c8229fbe273554c0c97cccee45d5967f5df1b9f) fix(cli.js): detect `node-` binary, closes [#6427](https://www.github.com/tauri-apps/tauri/pull/6427) ([#6432](https://www.github.com/tauri-apps/tauri/pull/6432)) on 2023-03-16 +- Add `--png` option for the `icon` command to generate custom icon sizes. + - [9d214412](https://www.github.com/tauri-apps/tauri/commit/9d2144128fc5fad67d8404bce95f82297ebb0e4a) feat(cli): add option to make custom icon sizes, closes [#5121](https://www.github.com/tauri-apps/tauri/pull/5121) ([#5246](https://www.github.com/tauri-apps/tauri/pull/5246)) on 2022-12-27 +- Skip the password prompt on the build command when `TAURI_KEY_PASSWORD` environment variable is empty and the `--ci` argument is provided or the `CI` environment variable is set. + - [d4f89af1](https://www.github.com/tauri-apps/tauri/commit/d4f89af18d69fd95a4d8a1ede8442547c6a6d0ee) feat: skip password prompt on the build command if CI is set fixes [#6089](https://www.github.com/tauri-apps/tauri/pull/6089) on 2023-01-18 +- Fix `default-run` not deserialized. + - [57c6bf07](https://www.github.com/tauri-apps/tauri/commit/57c6bf07bb380847abdf27c3fff9891d99c1c98c) fix(cli): fix default-run not deserialized ([#6584](https://www.github.com/tauri-apps/tauri/pull/6584)) on 2023-03-30 +- Fixes HTML serialization removing template tags on the dev server. + - [314f0e21](https://www.github.com/tauri-apps/tauri/commit/314f0e212fd2b9e452bfe3424cdce2b0bf37b5d7) fix(cli): web_dev_server html template serialization (fix [#6165](https://www.github.com/tauri-apps/tauri/pull/6165)) ([#6166](https://www.github.com/tauri-apps/tauri/pull/6166)) on 2023-01-29 +- Use escaping on Handlebars templates. + - [6d6b6e65](https://www.github.com/tauri-apps/tauri/commit/6d6b6e653ea70fc02794f723092cdc860995c259) feat: configure escaping on handlebars templates ([#6678](https://www.github.com/tauri-apps/tauri/pull/6678)) on 2023-05-02 +- Add initial support for building `nsis` bundles on non-Windows platforms. + - [60e6f6c3](https://www.github.com/tauri-apps/tauri/commit/60e6f6c3f1605f3064b5bb177992530ff788ccf0) feat(bundler): Add support for creating NSIS bundles on unix hosts ([#5788](https://www.github.com/tauri-apps/tauri/pull/5788)) on 2023-01-19 +- Add `nsis` bundle target + - [c94e1326](https://www.github.com/tauri-apps/tauri/commit/c94e1326a7c0767a13128a8b1d327a00156ece12) feat(bundler): add `nsis`, closes [#4450](https://www.github.com/tauri-apps/tauri/pull/4450), closes [#2319](https://www.github.com/tauri-apps/tauri/pull/2319) ([#4674](https://www.github.com/tauri-apps/tauri/pull/4674)) on 2023-01-03 +- Remove default features from Cargo.toml template. + - [b08ae637](https://www.github.com/tauri-apps/tauri/commit/b08ae637a0f58b38cbce9b8a1fa0b6c5dc0cfd05) fix(cli): remove default features from template ([#6074](https://www.github.com/tauri-apps/tauri/pull/6074)) on 2023-01-17 +- Use Ubuntu 20.04 to compile the CLI, increasing the minimum libc version required. + +## \[1.2.3] + +- Pin `ignore` to `=0.4.18`. + - [adcb082b](https://www.github.com/tauri-apps/tauri/commit/adcb082b1651ecb2a6208b093e12f4185aa3fc98) chore(deps): pin `ignore` to =0.4.18 on 2023-01-17 + +## \[1.2.2] + +- Detect SvelteKit and Vite for the init and info commands. + - [9d872ab8](https://www.github.com/tauri-apps/tauri/commit/9d872ab8728b1b121909af434adcd5936e5afb7d) feat(cli): detect SvelteKit and Vite ([#5742](https://www.github.com/tauri-apps/tauri/pull/5742)) on 2022-12-02 +- Detect SolidJS and SolidStart for the init and info commands. + - [9e7ce0a8](https://www.github.com/tauri-apps/tauri/commit/9e7ce0a8eef4bf3536645976e3e09162fbf772ab) feat(cli): detect SolidJS and SolidStart ([#5758](https://www.github.com/tauri-apps/tauri/pull/5758)) on 2022-12-08 +- Use older icon types to work around a macOS bug resulting in corrupted 16x16px and 32x32px icons in bundled apps. + - [2d545eff](https://www.github.com/tauri-apps/tauri/commit/2d545eff58734ec70f23f11a429d35435cdf090e) fix(cli): corrupted icons in bundled macOS icons ([#5698](https://www.github.com/tauri-apps/tauri/pull/5698)) on 2022-11-28 + +## \[1.2.1] + +- Fixes injection of Cargo features defined in the configuration file. + - [1ecaeb29](https://www.github.com/tauri-apps/tauri/commit/1ecaeb29aa798f591f6488dc6c3a7a8d22f6073e) fix(cli): inject config feature flags when features arg is not provided on 2022-11-18 + +## \[1.2.0] + +- Detect JSON5 and TOML configuration files in the dev watcher. + - [e7ccbd85](https://www.github.com/tauri-apps/tauri/commit/e7ccbd8573f6b9124e80c0b67fa2365729c3c196) feat(cli): detect JSON5 and TOML configuration files in the dev watcher ([#5439](https://www.github.com/tauri-apps/tauri/pull/5439)) on 2022-10-19 +- Log dev watcher file change detection. + - [9076d5d2](https://www.github.com/tauri-apps/tauri/commit/9076d5d2e76d432aef475ba403e9ab5bd3b9d2b0) feat(cli): add prompt information when file changing detected, closes [#5417](https://www.github.com/tauri-apps/tauri/pull/5417) ([#5428](https://www.github.com/tauri-apps/tauri/pull/5428)) on 2022-10-19 +- Fix crash when nodejs binary has the version in its name, for example `node18` or when running through deno. + - [7a231cd1](https://www.github.com/tauri-apps/tauri/commit/7a231cd1c99101f63354b13bb36223568d2f0a11) fix(cli): detect deno ([#5475](https://www.github.com/tauri-apps/tauri/pull/5475)) on 2022-10-28 +- Changed the project template to not enable all APIs by default. + - [582c25a0](https://www.github.com/tauri-apps/tauri/commit/582c25a0f0fa2725d786ec4edd0defe7811ad6e8) refactor(cli): disable api-all on templates ([#5538](https://www.github.com/tauri-apps/tauri/pull/5538)) on 2022-11-03 + +## \[1.1.1] + +- Fix wrong cli metadata that caused new projects (created through `tauri init`) fail to build + - [db26aaf2](https://www.github.com/tauri-apps/tauri/commit/db26aaf2b44ce5335c9223c571ef2b2175e0cd6d) fix: fix wrong cli metadata ([#5214](https://www.github.com/tauri-apps/tauri/pull/5214)) on 2022-09-16 + +## \[1.1.0] + +- Allow adding `build > beforeBundleCommand` in tauri.conf.json to run a shell command before the bundling phase. + - [57ab9847](https://www.github.com/tauri-apps/tauri/commit/57ab9847eb2d8c9a5da584b873b7c072e9ee26bf) feat(cli): add `beforeBundleCommand`, closes [#4879](https://www.github.com/tauri-apps/tauri/pull/4879) ([#4893](https://www.github.com/tauri-apps/tauri/pull/4893)) on 2022-08-09 +- Change `before_dev_command` and `before_build_command` config value to allow configuring the current working directory. + - [d6f7d3cf](https://www.github.com/tauri-apps/tauri/commit/d6f7d3cfe8a7ec8d68c8341016c4e0a3103da587) Add cwd option to `before` commands, add wait option to dev [#4740](https://www.github.com/tauri-apps/tauri/pull/4740) [#3551](https://www.github.com/tauri-apps/tauri/pull/3551) ([#4834](https://www.github.com/tauri-apps/tauri/pull/4834)) on 2022-08-02 +- Allow configuring the `before_dev_command` to force the CLI to wait for the command to finish before proceeding. + - [d6f7d3cf](https://www.github.com/tauri-apps/tauri/commit/d6f7d3cfe8a7ec8d68c8341016c4e0a3103da587) Add cwd option to `before` commands, add wait option to dev [#4740](https://www.github.com/tauri-apps/tauri/pull/4740) [#3551](https://www.github.com/tauri-apps/tauri/pull/3551) ([#4834](https://www.github.com/tauri-apps/tauri/pull/4834)) on 2022-08-02 +- Check if the default build target is set in the Cargo configuration. + - [436f3d8d](https://www.github.com/tauri-apps/tauri/commit/436f3d8d66727f5b64165522f0b55f4ab54bd1ae) feat(cli): load Cargo configuration to check default build target ([#4990](https://www.github.com/tauri-apps/tauri/pull/4990)) on 2022-08-21 +- Use `cargo metadata` to detect the workspace root and target directory. + - [fea70eff](https://www.github.com/tauri-apps/tauri/commit/fea70effad219c0794d919f8834fa1a1ffd204c7) refactor(cli): Use `cargo metadata` to detect the workspace root and target directory, closes [#4632](https://www.github.com/tauri-apps/tauri/pull/4632), [#4928](https://www.github.com/tauri-apps/tauri/pull/4928). ([#4932](https://www.github.com/tauri-apps/tauri/pull/4932)) on 2022-08-21 +- Prompt for `beforeDevCommand` and `beforeBuildCommand` in `tauri init`. + - [6d4945c9](https://www.github.com/tauri-apps/tauri/commit/6d4945c9f06cd1f7018e1c48686ba682aae817df) feat(cli): prompt for before\*Command, closes [#4691](https://www.github.com/tauri-apps/tauri/pull/4691) ([#4721](https://www.github.com/tauri-apps/tauri/pull/4721)) on 2022-07-25 +- Added support to configuration files in TOML format (Tauri.toml file). + - [ae83d008](https://www.github.com/tauri-apps/tauri/commit/ae83d008f9e1b89bfc8dddaca42aa5c1fbc36f6d) feat: add support to TOML config file `Tauri.toml`, closes [#4806](https://www.github.com/tauri-apps/tauri/pull/4806) ([#4813](https://www.github.com/tauri-apps/tauri/pull/4813)) on 2022-08-02 +- Automatically use any `.taurignore` file as ignore rules for dev watcher and app path finder. + - [596fa08d](https://www.github.com/tauri-apps/tauri/commit/596fa08d48e371c7bd29e1ef799119ac8fca0d0b) feat(cli): automatically use `.taurignore`, ref [#4617](https://www.github.com/tauri-apps/tauri/pull/4617) ([#4623](https://www.github.com/tauri-apps/tauri/pull/4623)) on 2022-07-28 +- Enable WiX FIPS compliance when the `TAURI_FIPS_COMPLIANT` environment variable is set to `true`. + - [d88b9de7](https://www.github.com/tauri-apps/tauri/commit/d88b9de7aaeaaa2e42e4795dbc2b8642b5ae7a50) feat(core): add `fips_compliant` wix config option, closes [#4541](https://www.github.com/tauri-apps/tauri/pull/4541) ([#4843](https://www.github.com/tauri-apps/tauri/pull/4843)) on 2022-08-04 +- Fixes dev watcher incorrectly exiting the CLI when sequential file updates are detected. + - [47fab680](https://www.github.com/tauri-apps/tauri/commit/47fab6809a1e23b3b9a84695e2d91ff0826ba79a) fix(cli): dev watcher incorrectly killing process on multiple file write ([#4684](https://www.github.com/tauri-apps/tauri/pull/4684)) on 2022-07-25 +- Add `libc` field to Node packages. + - [f7d2dfc7](https://www.github.com/tauri-apps/tauri/commit/f7d2dfc7a6d086dd1a218d6c1492b3fef8a64f03) chore: add libc field to node packages ([#4856](https://www.github.com/tauri-apps/tauri/pull/4856)) on 2022-08-04 +- Set the `MACOSX_DEPLOYMENT_TARGET` environment variable with the configuration `minimum_system_version` value. + - [fa23310f](https://www.github.com/tauri-apps/tauri/commit/fa23310f23cb9e6a02ec2524f1ef394a5b42990e) fix(cli): set MACOSX_DEPLOYMENT_TARGET env var, closes [#4704](https://www.github.com/tauri-apps/tauri/pull/4704) ([#4842](https://www.github.com/tauri-apps/tauri/pull/4842)) on 2022-08-02 +- Added `--no-watch` argument to the `dev` command to disable the file watcher. + - [0983d7ce](https://www.github.com/tauri-apps/tauri/commit/0983d7ce7f24ab43f9ae7b5e1177ff244d8885a8) feat(cli): add `--no-watch` argument to the dev command, closes [#4617](https://www.github.com/tauri-apps/tauri/pull/4617) ([#4793](https://www.github.com/tauri-apps/tauri/pull/4793)) on 2022-07-29 +- Validate updater signature matches configured public key. + - [b2a8930b](https://www.github.com/tauri-apps/tauri/commit/b2a8930b3c4b72c50ce72e73575f42c9cbe91bad) feat(cli): validate updater private key when signing ([#4754](https://www.github.com/tauri-apps/tauri/pull/4754)) on 2022-07-25 + +## \[1.0.5] + +- Correctly fill the architecture when building Debian packages targeting ARM64 (aarch64). + - Bumped due to a bump in cli.rs. + - [635f23b8](https://www.github.com/tauri-apps/tauri/commit/635f23b88adbb8726d628f67840709cd870836dc) fix(bundler): correctly set debian architecture for aarch64 ([#4700](https://www.github.com/tauri-apps/tauri/pull/4700)) on 2022-07-17 + +## \[1.0.4] + +- Do not capture and force colors of `cargo build` output. + - [c635a0da](https://www.github.com/tauri-apps/tauri/commit/c635a0dad437860d54109adffaf245b7c21bc684) refactor(cli): do not capture and force colors of cargo build output ([#4627](https://www.github.com/tauri-apps/tauri/pull/4627)) on 2022-07-12 +- Reduce the amount of allocations when converting cases. + - [bc370e32](https://www.github.com/tauri-apps/tauri/commit/bc370e326810446e15b1f50fb962b980114ba16b) feat: reduce the amount of `heck`-related allocations ([#4634](https://www.github.com/tauri-apps/tauri/pull/4634)) on 2022-07-11 + +## \[1.0.3] + +- Changed the app template to not set the default app menu as it is now set automatically on macOS which is the platform that needs a menu to function properly. + - [91055883](https://www.github.com/tauri-apps/tauri/commit/9105588373cc8401bd9ad79bdef26f509b2d76b7) feat: add implicit default menu for macOS only, closes [#4551](https://www.github.com/tauri-apps/tauri/pull/4551) ([#4570](https://www.github.com/tauri-apps/tauri/pull/4570)) on 2022-07-04 +- Improved bundle identifier validation showing the exact source of the configuration value. + - [8e3e7fc6](https://www.github.com/tauri-apps/tauri/commit/8e3e7fc64641afc7a6833bc93205e6f525562545) feat(cli): improve bundle identifier validation, closes [#4589](https://www.github.com/tauri-apps/tauri/pull/4589) ([#4596](https://www.github.com/tauri-apps/tauri/pull/4596)) on 2022-07-05 +- Improve configuration deserialization error messages. + - [9170c920](https://www.github.com/tauri-apps/tauri/commit/9170c9207044fa561535f624916dfdbaa41ff79d) feat(core): improve config deserialization error messages ([#4607](https://www.github.com/tauri-apps/tauri/pull/4607)) on 2022-07-06 +- Revert the `run` command to run in a separate thread. + - [f65eb4f8](https://www.github.com/tauri-apps/tauri/commit/f65eb4f84d8e511cd30d01d20a8223a297f7e584) fix(cli.js): revert `run` command to be nonblocking on 2022-07-04 +- Skip the static link of the `vcruntime140.dll` if the `STATIC_VCRUNTIME` environment variable is set to `false`. + - [2e61abaa](https://www.github.com/tauri-apps/tauri/commit/2e61abaa9ae5d7a41ca1fa6505b5d6c368625ce5) feat(cli): allow dynamic link vcruntime, closes [#4565](https://www.github.com/tauri-apps/tauri/pull/4565) ([#4601](https://www.github.com/tauri-apps/tauri/pull/4601)) on 2022-07-06 +- The `TAURI_CONFIG` environment variable now represents the configuration to be merged instead of the entire JSON. + - [fa028ebf](https://www.github.com/tauri-apps/tauri/commit/fa028ebf3c8ca7b43a70d283a01dbea86217594f) refactor: do not pass entire config from CLI to core, send patch instead ([#4598](https://www.github.com/tauri-apps/tauri/pull/4598)) on 2022-07-06 +- Watch for Cargo workspace members in the `dev` file watcher. + - [dbb8c87b](https://www.github.com/tauri-apps/tauri/commit/dbb8c87b96dec9942b1bf877b29bafb8246514d4) feat(cli): watch Cargo workspaces in the dev command, closes [#4222](https://www.github.com/tauri-apps/tauri/pull/4222) ([#4572](https://www.github.com/tauri-apps/tauri/pull/4572)) on 2022-07-03 + +## \[1.0.2] + +- Fixes a crash on the `signer sign` command. + - [8e808fec](https://www.github.com/tauri-apps/tauri/commit/8e808fece95f2e506acf2c446d37b9913fd67d50) fix(cli.rs): conflicts_with arg doesn't exist closes ([#4538](https://www.github.com/tauri-apps/tauri/pull/4538)) on 2022-06-30 + +## \[1.0.1] + +- No longer adds the `pkg-config` dependency to `.deb` packages when the `systemTray` is used. + This only works with recent versions of `libappindicator-sys` (including https://github.com/tauri-apps/libappindicator-rs/pull/38), + so a `cargo update` may be necessary if you create `.deb` bundles and use the tray feature. + - [0e6edeb1](https://www.github.com/tauri-apps/tauri/commit/0e6edeb14f379af1e02a7cebb4e3a5c9e87ebf7f) fix(cli): Don't add `pkg-config` to `deb` ([#4508](https://www.github.com/tauri-apps/tauri/pull/4508)) on 2022-06-29 +- AppImage bundling will now prefer bundling correctly named appindicator library (including `.1` version suffix). With a symlink for compatibility with the old naming. + - [bf45ca1d](https://www.github.com/tauri-apps/tauri/commit/bf45ca1df6691c05bdf72c5716cc01e89a7791d4) fix(cli,bundler): prefer AppImage libraries with ABI version ([#4505](https://www.github.com/tauri-apps/tauri/pull/4505)) on 2022-06-29 +- Improve error message when `cargo` is not installed. + - [e0e5f772](https://www.github.com/tauri-apps/tauri/commit/e0e5f772430f6349ec99ba891e601331e376e3c7) feat(cli): improve `cargo not found` error message, closes [#4428](https://www.github.com/tauri-apps/tauri/pull/4428) ([#4430](https://www.github.com/tauri-apps/tauri/pull/4430)) on 2022-06-21 +- The app template now only sets the default menu on macOS. + - [5105b428](https://www.github.com/tauri-apps/tauri/commit/5105b428c4726b2179cd4b3244350d1a1ee73734) feat(cli): change app template to only set default menu on macOS ([#4518](https://www.github.com/tauri-apps/tauri/pull/4518)) on 2022-06-29 +- Warn if updater is enabled but not in the bundle target list. + - [31c15cd2](https://www.github.com/tauri-apps/tauri/commit/31c15cd2bd94dbe39fb94982a15cbe02ac5d8925) docs(config): enhance documentation for bundle targets, closes [#3251](https://www.github.com/tauri-apps/tauri/pull/3251) ([#4418](https://www.github.com/tauri-apps/tauri/pull/4418)) on 2022-06-21 +- Check if target exists and is installed on dev and build commands. + - [13b8a240](https://www.github.com/tauri-apps/tauri/commit/13b8a2403d1353a8c3a643fbc6b6e862af68376e) feat(cli): validate target argument ([#4458](https://www.github.com/tauri-apps/tauri/pull/4458)) on 2022-06-24 +- Fixes the covector configuration on the plugin templates. + - [b8a64d01](https://www.github.com/tauri-apps/tauri/commit/b8a64d01bab11f955b7bbdf323d0afa1a3db4b64) fix(cli): add prepublish scripts to the plugin templates on 2022-06-19 +- Set the binary name to the product name in development. + - [b025b9f5](https://www.github.com/tauri-apps/tauri/commit/b025b9f581ac1a6ae0a26789c2be1e9928fb0282) refactor(cli): set binary name on dev ([#4447](https://www.github.com/tauri-apps/tauri/pull/4447)) on 2022-06-23 +- Allow registering a `.gitignore` file to skip watching some project files and directories via the `TAURI_DEV_WATCHER_IGNORE_FILE` environment variable. + - [83186dd8](https://www.github.com/tauri-apps/tauri/commit/83186dd89768407984db35fb67c3cc51f50ea8f5) Read extra ignore file for dev watcher, closes [#4406](https://www.github.com/tauri-apps/tauri/pull/4406) ([#4409](https://www.github.com/tauri-apps/tauri/pull/4409)) on 2022-06-20 +- Fix shebang for `kill-children.sh`. + - [35dd51db](https://www.github.com/tauri-apps/tauri/commit/35dd51db6826ec1eed7b90082b9eb6b2a699b627) fix(cli): add shebang for kill-children.sh, closes [#4262](https://www.github.com/tauri-apps/tauri/pull/4262) ([#4416](https://www.github.com/tauri-apps/tauri/pull/4416)) on 2022-06-22 +- Update plugin templates to use newer `tauri-apps/create-pull-request` GitHub action. + - [07f90795](https://www.github.com/tauri-apps/tauri/commit/07f9079532a42f3517d96faeaf46cad6176b31ac) chore(cli): update plugin template tauri-apps/create-pull-request on 2022-06-19 +- Use UNIX path separator on the init `$schema` field. + - [01053045](https://www.github.com/tauri-apps/tauri/commit/010530459ef62c48eed68ca965f2688accabcf69) chore(cli): use unix path separator on $schema ([#4384](https://www.github.com/tauri-apps/tauri/pull/4384)) on 2022-06-19 +- The `info` command now can check the Cargo lockfile on workspaces. + - [12f65219](https://www.github.com/tauri-apps/tauri/commit/12f65219ea75a51ebd38659ddce1563e015a036c) fix(cli): read lockfile from workspace on the info command, closes [#4232](https://www.github.com/tauri-apps/tauri/pull/4232) ([#4423](https://www.github.com/tauri-apps/tauri/pull/4423)) on 2022-06-21 +- Preserve the `Cargo.toml` formatting when the features array is not changed. + - [6650e5d6](https://www.github.com/tauri-apps/tauri/commit/6650e5d6720c215530ca1fdccd19bd2948dd6ca3) fix(cli): preserve Cargo manifest formatting when possible ([#4431](https://www.github.com/tauri-apps/tauri/pull/4431)) on 2022-06-21 +- Change the updater signature metadata to include the file name instead of its full path. + - [094b3eb3](https://www.github.com/tauri-apps/tauri/commit/094b3eb352bcf5de28414015e7c44290d619ea8c) fix(cli): file name instead of path on updater sig comment, closes [#4467](https://www.github.com/tauri-apps/tauri/pull/4467) ([#4484](https://www.github.com/tauri-apps/tauri/pull/4484)) on 2022-06-27 +- Validate bundle identifier as it must only contain alphanumeric characters, hyphens and periods. + - [0674a801](https://www.github.com/tauri-apps/tauri/commit/0674a80129d7c31bc93257849afc0a5069129fed) fix: assert config.bundle.identifier to be only alphanumeric, hyphens or dots. closes [#4359](https://www.github.com/tauri-apps/tauri/pull/4359) ([#4363](https://www.github.com/tauri-apps/tauri/pull/4363)) on 2022-06-17 + +## \[1.0.0] + +- Upgrade to `stable`! + - [f4bb30cc](https://www.github.com/tauri-apps/tauri/commit/f4bb30cc73d6ba9b9ef19ef004dc5e8e6bb901d3) feat(covector): prepare for v1 ([#4351](https://www.github.com/tauri-apps/tauri/pull/4351)) on 2022-06-15 + +## \[1.0.0-rc.16] + +- Use the default window menu in the app template. + - [4c4acc30](https://www.github.com/tauri-apps/tauri/commit/4c4acc3094218dd9cee0f1ad61810c979e0b41fa) feat: implement `Default` for `Menu`, closes [#2398](https://www.github.com/tauri-apps/tauri/pull/2398) ([#4291](https://www.github.com/tauri-apps/tauri/pull/4291)) on 2022-06-15 + +## \[1.0.0-rc.15] + +- Removed the tray icon from the Debian and AppImage bundles since they are embedded in the binary now. + - [4ce8e228](https://www.github.com/tauri-apps/tauri/commit/4ce8e228134cd3f22973b74ef26ca0d165fbbbd9) refactor(core): use `Icon` for tray icons ([#4342](https://www.github.com/tauri-apps/tauri/pull/4342)) on 2022-06-14 + +## \[1.0.0-rc.14] + +- Set the `TRAY_LIBRARY_PATH` environment variable to make the bundle copy the appindicator library to the AppImage. + - [34552444](https://www.github.com/tauri-apps/tauri/commit/3455244436578003a5fbb447b039e5c8971152ec) feat(cli): bundle appindicator library in the AppImage, closes [#3859](https://www.github.com/tauri-apps/tauri/pull/3859) ([#4267](https://www.github.com/tauri-apps/tauri/pull/4267)) on 2022-06-07 +- Set the `APPIMAGE_BUNDLE_GSTREAMER` environment variable to make the bundler copy additional gstreamer files to the AppImage. + - [d335fae9](https://www.github.com/tauri-apps/tauri/commit/d335fae92cdcbb0ee18aad4e54558914afa3e778) feat(bundler): bundle additional gstreamer files, closes [#4092](https://www.github.com/tauri-apps/tauri/pull/4092) ([#4271](https://www.github.com/tauri-apps/tauri/pull/4271)) on 2022-06-10 +- Configure the AppImage bundler to copy the `/usr/bin/xdg-open` binary if it exists and the shell `open` API is enabled. + - [2322ac11](https://www.github.com/tauri-apps/tauri/commit/2322ac11cf6290c6bf65413048a049c8072f863b) fix(bundler): bundle `/usr/bin/xdg-open` in appimage if open API enabled ([#4265](https://www.github.com/tauri-apps/tauri/pull/4265)) on 2022-06-04 +- Fixes multiple occurrences handling of the `bundles` and `features` arguments. + - [f685df39](https://www.github.com/tauri-apps/tauri/commit/f685df399a5a05480b6e4f5d92da71f3b87895ef) fix(cli): parsing of arguments with multiple values, closes [#4231](https://www.github.com/tauri-apps/tauri/pull/4231) ([#4233](https://www.github.com/tauri-apps/tauri/pull/4233)) on 2022-05-29 +- Log command output in real time instead of waiting for it to finish. + - [76d1eaae](https://www.github.com/tauri-apps/tauri/commit/76d1eaaebda5c8f6b0d41bf6587945e98cd441f3) feat(cli): debug command output in real time ([#4318](https://www.github.com/tauri-apps/tauri/pull/4318)) on 2022-06-12 +- Configure the `STATIC_VCRUNTIME` environment variable so `tauri-build` statically links it on the build command. + - [d703d27a](https://www.github.com/tauri-apps/tauri/commit/d703d27a707edc028f13b35603205da1133fcc2b) fix(build): statically link VC runtime only on `tauri build` ([#4292](https://www.github.com/tauri-apps/tauri/pull/4292)) on 2022-06-07 +- Use the `TAURI_TRAY` environment variable to determine which package should be added to the Debian `depends` section. Possible values are `ayatana` and `gtk`. + - [6216eb49](https://www.github.com/tauri-apps/tauri/commit/6216eb49e72863bfb6d4c9edb8827b21406ac393) refactor(core): drop `ayatana-tray` and `gtk-tray` Cargo features ([#4247](https://www.github.com/tauri-apps/tauri/pull/4247)) on 2022-06-02 + +## \[1.0.0-rc.13] + +- Check if `$CWD/src-tauri/tauri.conf.json` exists before walking through the file tree to find the tauri dir in case the whole project is gitignored. + - [bd8f3e29](https://www.github.com/tauri-apps/tauri/commit/bd8f3e298a0cb71809f2e93cc3ebc8e6e5b6a626) fix(cli): manual config lookup to handle gitignored folders, fixes [#3527](https://www.github.com/tauri-apps/tauri/pull/3527) ([#4224](https://www.github.com/tauri-apps/tauri/pull/4224)) on 2022-05-26 +- Statically link the Visual C++ runtime instead of using a merge module on the installer. + - [bb061509](https://www.github.com/tauri-apps/tauri/commit/bb061509fb674bef86ecbc1de3aa8f3e367a9907) refactor(core): statically link vcruntime, closes [#4122](https://www.github.com/tauri-apps/tauri/pull/4122) ([#4227](https://www.github.com/tauri-apps/tauri/pull/4227)) on 2022-05-27 + +## \[1.0.0-rc.12] + +- Properly fetch the NPM dependency information when using Yarn 2+. + - [cdfa6255](https://www.github.com/tauri-apps/tauri/commit/cdfa62551115586725bd3e4c04f12c5256f20790) fix(cli): properly read info when using yarn 2+, closes [#4106](https://www.github.com/tauri-apps/tauri/pull/4106) ([#4193](https://www.github.com/tauri-apps/tauri/pull/4193)) on 2022-05-23 + +## \[1.0.0-rc.11] + +- Allow configuring the display options for the MSI execution allowing quieter updates. + - [9f2c3413](https://www.github.com/tauri-apps/tauri/commit/9f2c34131952ea83c3f8e383bc3cec7e1450429f) feat(core): configure msiexec display options, closes [#3951](https://www.github.com/tauri-apps/tauri/pull/3951) ([#4061](https://www.github.com/tauri-apps/tauri/pull/4061)) on 2022-05-15 + +## \[1.0.0-rc.10] + +- Resolve binary file extension from target triple instead of compile-time checks to allow cross compilation. + - [4562e671](https://www.github.com/tauri-apps/tauri/commit/4562e671e4795e9386429348bf738f7078706945) fix(build): append .exe binary based on target triple instead of running OS, closes [#3870](https://www.github.com/tauri-apps/tauri/pull/3870) ([#4032](https://www.github.com/tauri-apps/tauri/pull/4032)) on 2022-05-03 +- Fixes text overflow on `tauri dev` on Windows. + - [094534d1](https://www.github.com/tauri-apps/tauri/commit/094534d138a9286e4746b61adff2da616e3b6a61) fix(cli): dev command stderr text overflow on Windows, closes [#3995](https://www.github.com/tauri-apps/tauri/pull/3995) ([#4000](https://www.github.com/tauri-apps/tauri/pull/4000)) on 2022-04-29 +- Improve CLI's logging output, making use of the standard rust `log` system. + - [35f21471](https://www.github.com/tauri-apps/tauri/commit/35f2147161e6697cbd2824681eeaf870b5a991c2) feat(cli): Improve CLI logging ([#4060](https://www.github.com/tauri-apps/tauri/pull/4060)) on 2022-05-07 +- Don't override the default keychain on macOS while code signing. + - [a4fcaf1d](https://www.github.com/tauri-apps/tauri/commit/a4fcaf1d04aafc3b4d42186f0fb386797d959a9d) fix: don't override default keychain, closes [#4008](https://www.github.com/tauri-apps/tauri/pull/4008) ([#4053](https://www.github.com/tauri-apps/tauri/pull/4053)) on 2022-05-05 +- - Remove startup delay in `tauri dev` caused by checking for a newer cli version. The check is now done upon process exit. +- Add `TAURI_SKIP_UPDATE_CHECK` env variable to skip checking for a newer CLI version. +- [bbabc8cd](https://www.github.com/tauri-apps/tauri/commit/bbabc8cd1ea2c1f6806610fd2d533c99305d320c) fix(cli.rs): remove startup delay in `tauri dev` ([#3999](https://www.github.com/tauri-apps/tauri/pull/3999)) on 2022-04-29 +- Fix `tauri info` panic when a package isn't installed. + - [4f0f3187](https://www.github.com/tauri-apps/tauri/commit/4f0f3187c9e69262ef28350331b368c831ab930a) fix(cli.rs): fix `tauri info` panic when a package isn't installed, closes [#3985](https://www.github.com/tauri-apps/tauri/pull/3985) ([#3996](https://www.github.com/tauri-apps/tauri/pull/3996)) on 2022-04-29 +- Added `$schema` support to `tauri.conf.json`. + - [715cbde3](https://www.github.com/tauri-apps/tauri/commit/715cbde3842a916c4ebeab2cab348e1774b5c192) feat(config): add `$schema` to `tauri.conf.json`, closes [#3464](https://www.github.com/tauri-apps/tauri/pull/3464) ([#4031](https://www.github.com/tauri-apps/tauri/pull/4031)) on 2022-05-03 +- **Breaking change:** The `dev` command now reads the custom config file from CWD instead of the Tauri folder. + - [a1929c6d](https://www.github.com/tauri-apps/tauri/commit/a1929c6dacccd00af4cdbcc4d29cfb98d8428f55) fix(cli): always read custom config file from CWD, closes [#4067](https://www.github.com/tauri-apps/tauri/pull/4067) ([#4074](https://www.github.com/tauri-apps/tauri/pull/4074)) on 2022-05-07 +- Fixes a Powershell crash when sending SIGINT to the dev command. + - [32048486](https://www.github.com/tauri-apps/tauri/commit/320484866b83ecabb01eb58d158e0fedd9dd08be) fix(cli): powershell crashing on SIGINT, closes [#3997](https://www.github.com/tauri-apps/tauri/pull/3997) ([#4007](https://www.github.com/tauri-apps/tauri/pull/4007)) on 2022-04-29 +- Prevent building when the bundle identifier is the default `com.tauri.dev`. + - [95726ebb](https://www.github.com/tauri-apps/tauri/commit/95726ebb6180d371be44bff9f16ca1eee049006a) feat(cli): prevent default bundle identifier from building, closes [#4041](https://www.github.com/tauri-apps/tauri/pull/4041) ([#4042](https://www.github.com/tauri-apps/tauri/pull/4042)) on 2022-05-04 + +## \[1.0.0-rc.9] + +- Exit CLI when Cargo returns a non-compilation error in `tauri dev`. + - [b5622882](https://www.github.com/tauri-apps/tauri/commit/b5622882cf3748e1e5a90915f415c0cd922aaaf8) fix(cli): exit on non-compilation Cargo errors, closes [#3930](https://www.github.com/tauri-apps/tauri/pull/3930) ([#3942](https://www.github.com/tauri-apps/tauri/pull/3942)) on 2022-04-22 +- Notify CLI update when running `tauri dev`. + - [a649aad7](https://www.github.com/tauri-apps/tauri/commit/a649aad7ad26d4578699370d6e63d80edeca1f97) feat(cli): check and notify about updates on `tauri dev`, closes [#3789](https://www.github.com/tauri-apps/tauri/pull/3789) ([#3960](https://www.github.com/tauri-apps/tauri/pull/3960)) on 2022-04-25 +- Kill the `beforeDevCommand` and app processes if the dev command returns an error. + - [485c9743](https://www.github.com/tauri-apps/tauri/commit/485c97438ac956d86bcf3794ceaa626bef968a4e) fix(cli): kill beforeDevCommand if dev code returns an error ([#3907](https://www.github.com/tauri-apps/tauri/pull/3907)) on 2022-04-19 +- Fix `info` command showing outdated text for latest versions. + - [73a4b74a](https://www.github.com/tauri-apps/tauri/commit/73a4b74aea8544e6fda51c1f6697630b0768072c) fix(cli.rs/info): don't show outdated text for latest versions ([#3829](https://www.github.com/tauri-apps/tauri/pull/3829)) on 2022-04-02 +- **Breaking change:** Enable default Cargo features except `tauri/custom-protocol` on the dev command. + - [f2a30d8b](https://www.github.com/tauri-apps/tauri/commit/f2a30d8bc54fc3ba49e16f69a413eca5f61a9b1f) refactor(core): use ayatana appindicator by default, keep option to use gtk ([#3916](https://www.github.com/tauri-apps/tauri/pull/3916)) on 2022-04-19 +- Kill the `beforeDevCommand` process recursively on Unix. + - [e251e1b0](https://www.github.com/tauri-apps/tauri/commit/e251e1b0991d26ab10aea33cfb228f3e7f0f85b5) fix(cli): kill before dev command recursively on Unix, closes [#2794](https://www.github.com/tauri-apps/tauri/pull/2794) ([#3848](https://www.github.com/tauri-apps/tauri/pull/3848)) on 2022-04-03 + +## \[1.0.0-rc.8] + +- Allows the `tauri.conf.json` file to be git ignored on the path lookup function. + - [cc7c2d77](https://www.github.com/tauri-apps/tauri/commit/cc7c2d77da2e4a39ec2a97b080d41a719e6d0161) feat(cli): allow conf path to be gitignored, closes [#3636](https://www.github.com/tauri-apps/tauri/pull/3636) ([#3683](https://www.github.com/tauri-apps/tauri/pull/3683)) on 2022-03-13 +- Remove `minimumSystemVersion: null` from the application template configuration. + - [c81534eb](https://www.github.com/tauri-apps/tauri/commit/c81534ebd873c358e0346c7949aeb171803149a5) feat(cli): use default macOS minimum system version when it is empty ([#3658](https://www.github.com/tauri-apps/tauri/pull/3658)) on 2022-03-13 +- Improve readability of the `info` subcommand output. + - [49d2f13f](https://www.github.com/tauri-apps/tauri/commit/49d2f13fc07d763d5de9bf4b19d00c901776c11d) feat(cli): colorful cli ([#3635](https://www.github.com/tauri-apps/tauri/pull/3635)) on 2022-03-08 +- Fixes DMG bundling on macOS 12.3. + - [348a1ab5](https://www.github.com/tauri-apps/tauri/commit/348a1ab59d2697478a594016016f1fccbf1ac054) fix(bundler): DMG bundling on macOS 12.3 cannot use bless, closes [#3719](https://www.github.com/tauri-apps/tauri/pull/3719) ([#3721](https://www.github.com/tauri-apps/tauri/pull/3721)) on 2022-03-18 +- Fixes resources bundling on Windows when the path is on the root of the Tauri folder. + - [4c84559e](https://www.github.com/tauri-apps/tauri/commit/4c84559e1f3019e7aa2666b10a1a0bd97bb09d24) fix(cli): root resource bundling on Windows, closes [#3539](https://www.github.com/tauri-apps/tauri/pull/3539) ([#3685](https://www.github.com/tauri-apps/tauri/pull/3685)) on 2022-03-13 + +## \[1.0.0-rc.6] + +- Added `tsp` config option under `tauri > bundle > windows`, which enables Time-Stamp Protocol (RFC 3161) for the timestamping + server under code signing on Windows if set to `true`. + - [bdd5f7c2](https://www.github.com/tauri-apps/tauri/commit/bdd5f7c2f03af4af8b60a9527e55bb18525d989b) fix: add support for Time-Stamping Protocol for Windows codesigning (fix [#3563](https://www.github.com/tauri-apps/tauri/pull/3563)) ([#3570](https://www.github.com/tauri-apps/tauri/pull/3570)) on 2022-03-07 +- Added `i686-pc-windows-msvc` to the prebuilt targets. + - [fb6744da](https://www.github.com/tauri-apps/tauri/commit/fb6744daa45165c7e00e5c01f7df0880d69ca509) feat(cli.js): add 32bit cli for windows ([#3540](https://www.github.com/tauri-apps/tauri/pull/3540)) on 2022-02-24 +- Change the `plugin init` templates to use the new `tauri::plugin::Builder` syntax. + - [f7acb061](https://www.github.com/tauri-apps/tauri/commit/f7acb061e4d1ecdbfe182793587632d7ba6d8eff) feat(cli): use plugin::Builder syntax on the plugin template ([#3606](https://www.github.com/tauri-apps/tauri/pull/3606)) on 2022-03-03 + +## \[1.0.0-rc.5] + +- Improve "waiting for your dev server to start" message. + - [5999379f](https://www.github.com/tauri-apps/tauri/commit/5999379fb06052a115f04f99274ab46d1eefd659) chore(cli): improve "waiting for dev server" message, closes [#3491](https://www.github.com/tauri-apps/tauri/pull/3491) ([#3504](https://www.github.com/tauri-apps/tauri/pull/3504)) on 2022-02-18 +- Do not panic if the updater private key password is wrong. + - [17f17a80](https://www.github.com/tauri-apps/tauri/commit/17f17a80f818bcc20c387583a6ff00a8e07ec533) fix(cli): do not panic if private key password is wrong, closes [#3449](https://www.github.com/tauri-apps/tauri/pull/3449) ([#3495](https://www.github.com/tauri-apps/tauri/pull/3495)) on 2022-02-17 +- Check the current folder before checking the directories on the app and tauri dir path lookup function. + - [a06de376](https://www.github.com/tauri-apps/tauri/commit/a06de3760184caa71acfe7a2fe2189a033b565f5) fix(cli): path lookup should not check subfolder before the current one ([#3465](https://www.github.com/tauri-apps/tauri/pull/3465)) on 2022-02-15 +- Fixes the signature of the `signer sign` command to not have duplicated short flags. + - [a9755514](https://www.github.com/tauri-apps/tauri/commit/a975551461f3698db3f3b6afa5101189aaeeada9) fix(cli): duplicated short flag for `signer sign`, closes [#3483](https://www.github.com/tauri-apps/tauri/pull/3483) ([#3492](https://www.github.com/tauri-apps/tauri/pull/3492)) on 2022-02-17 + +## \[1.0.0-rc.4] + +- Change the `run` function to take a callback and run asynchronously instead of blocking the event loop. + - [cd9a20b9](https://www.github.com/tauri-apps/tauri/commit/cd9a20b9ab013759b4bdb742f358988022450795) refactor(cli.js): run on separate thread ([#3436](https://www.github.com/tauri-apps/tauri/pull/3436)) on 2022-02-13 +- Improve error message when the dev runner command fails. + - [759d1afb](https://www.github.com/tauri-apps/tauri/commit/759d1afb86f3657f6071a2ae39c9be21e20ed22c) feat(cli): improve error message when dev runner command fails ([#3447](https://www.github.com/tauri-apps/tauri/pull/3447)) on 2022-02-13 +- Show full error message from `cli.rs` instead of just the outermost underlying error message. + - [63826010](https://www.github.com/tauri-apps/tauri/commit/63826010d1f38544f36afd3aac67c45d4608d15b) feat(cli.js): show full error message ([#3442](https://www.github.com/tauri-apps/tauri/pull/3442)) on 2022-02-13 +- Increase `tauri.conf.json` directory lookup depth to `3` and allow changing it with the `TAURI_PATH_DEPTH` environment variable. + - [c6031c70](https://www.github.com/tauri-apps/tauri/commit/c6031c7070c6bb7539bbfdfe42cb73012829c910) feat(cli): increase lookup depth, add env var option ([#3451](https://www.github.com/tauri-apps/tauri/pull/3451)) on 2022-02-13 +- Added `tauri-build`, `tao` and `wry` version to the `info` command output. + - [16f1173f](https://www.github.com/tauri-apps/tauri/commit/16f1173f456b1db543d0160df2c9828708bfc68a) feat(cli): add tao and wry version to the `info` output ([#3443](https://www.github.com/tauri-apps/tauri/pull/3443)) on 2022-02-13 + +## \[1.0.0-rc.3] + +- Change default value for the `freezePrototype` configuration to `false`. + - Bumped due to a bump in cli.rs. + - [3a4c0160](https://www.github.com/tauri-apps/tauri/commit/3a4c01606184be762adee055ddac803de0d28527) fix(core): change default `freezePrototype` to false, closes [#3416](https://www.github.com/tauri-apps/tauri/pull/3416) [#3406](https://www.github.com/tauri-apps/tauri/pull/3406) ([#3423](https://www.github.com/tauri-apps/tauri/pull/3423)) on 2022-02-12 + +## \[1.0.0-rc.2] + +- Fixes Tauri path resolution on projects without Git or a `.gitignore` file. + - [d8acbe11](https://www.github.com/tauri-apps/tauri/commit/d8acbe11492bd990e6983c7e63e0f1a8f1ea5c7c) fix(cli.rs): app path resolution on projects without git, closes [#3409](https://www.github.com/tauri-apps/tauri/pull/3409) ([#3410](https://www.github.com/tauri-apps/tauri/pull/3410)) on 2022-02-11 + +## \[1.0.0-rc.1] + +- Fix `init` command prompting for values even if the argument has been provided on the command line. + - [def76840](https://www.github.com/tauri-apps/tauri/commit/def76840257a1447723ecda13c807cf0c881f083) fix(cli.rs): do not prompt for `init` values if arg set ([#3400](https://www.github.com/tauri-apps/tauri/pull/3400)) on 2022-02-11 + - [41052dee](https://www.github.com/tauri-apps/tauri/commit/41052deeda2a00ee2b8ec2041c9c87c11de82ab2) fix(covector): add cli.js to change files on 2022-02-11 +- Fixes CLI freezing when running `light.exe` on Windows without the `--verbose` flag. + - [8beab636](https://www.github.com/tauri-apps/tauri/commit/8beab6363491e2a8757cc9fc0fa1eccc98ece916) fix(cli): build freezing on Windows, closes [#3399](https://www.github.com/tauri-apps/tauri/pull/3399) ([#3402](https://www.github.com/tauri-apps/tauri/pull/3402)) on 2022-02-11 +- Respect `.gitignore` configuration when looking for the folder with the `tauri.conf.json` file. + - [9c6c5a8c](https://www.github.com/tauri-apps/tauri/commit/9c6c5a8c52c6460d0b0a1a55300e1828262994ba) perf(cli.rs): improve performance of tauri dir lookup reading .gitignore ([#3405](https://www.github.com/tauri-apps/tauri/pull/3405)) on 2022-02-11 + - [41052dee](https://www.github.com/tauri-apps/tauri/commit/41052deeda2a00ee2b8ec2041c9c87c11de82ab2) fix(covector): add cli.js to change files on 2022-02-11 + +## \[1.0.0-rc.0] + +- Do not force Tauri application code on `src-tauri` folder and use a glob pattern to look for a subfolder with a `tauri.conf.json` file. + - [a8cff6b3](https://www.github.com/tauri-apps/tauri/commit/a8cff6b3bc3288a53d7cdc5b3cb95d371309d2d6) feat(cli): do not enforce `src-tauri` folder structure, closes [#2643](https://www.github.com/tauri-apps/tauri/pull/2643) ([#2654](https://www.github.com/tauri-apps/tauri/pull/2654)) on 2021-09-27 +- Added CommonJS output to the `dist` folder. + - [205b0dc8](https://www.github.com/tauri-apps/tauri/commit/205b0dc8f30bf70902979a2c0a08c8bc8c8e5360) feat(cli.js): add CommonJS dist files ([#2646](https://www.github.com/tauri-apps/tauri/pull/2646)) on 2021-09-23 +- Fixes `.ico` icon generation. + - [11db96e4](https://www.github.com/tauri-apps/tauri/commit/11db96e440e6cadc1c70992d07bfea3c448208b1) fix(cli.js): `.ico` icon generation, closes [#2692](https://www.github.com/tauri-apps/tauri/pull/2692) ([#2694](https://www.github.com/tauri-apps/tauri/pull/2694)) on 2021-10-02 +- Automatically unplug `@tauri-apps/cli` in yarn 2+ installations to fix the download of the rust-cli. + - [1e336b68](https://www.github.com/tauri-apps/tauri/commit/1e336b6872c3b78caf7c2c6e71e03016c6abdacf) fix(cli.js): Fix package installation on yarn 2+ ([#3012](https://www.github.com/tauri-apps/tauri/pull/3012)) on 2021-12-09 +- Read `package.json` and check for a `tauri` object containing the `appPath` string, which points to the tauri crate path. + - [fb2b9a52](https://www.github.com/tauri-apps/tauri/commit/fb2b9a52f594830c0a68ea40ea429a09892f7ba7) feat(cli.js): allow configuring tauri app path on package.json [#2752](https://www.github.com/tauri-apps/tauri/pull/2752) ([#3035](https://www.github.com/tauri-apps/tauri/pull/3035)) on 2021-12-09 +- Removed the `icon` command, now exposed as a separate package, see https://github.com/tauri-apps/tauricon. + - [58030172](https://www.github.com/tauri-apps/tauri/commit/58030172eddb2403a84b56a21b5bdcebca42c265) feat(tauricon): remove from cli ([#3293](https://www.github.com/tauri-apps/tauri/pull/3293)) on 2022-02-07 diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_APACHE-2.0 b/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_APACHE-2.0 new file mode 100644 index 0000000..f433b1a --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_APACHE-2.0 @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_MIT b/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_MIT new file mode 100644 index 0000000..b08530d --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/LICENSE_MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 - Present Tauri Apps Contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/README.md b/tools/join-backups/node_modules/@tauri-apps/cli/README.md new file mode 100644 index 0000000..2255c26 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/README.md @@ -0,0 +1,52 @@ +# @tauri-apps/cli + + + +[![status](https://img.shields.io/badge/status-stable-blue.svg)](https://github.com/tauri-apps/tauri/tree/dev) +[![License](https://img.shields.io/badge/License-MIT%20or%20Apache%202-green.svg)](https://opencollective.com/tauri) +[![test cli](https://img.shields.io/github/actions/workflow/status/tauri-apps/tauri/test-cli-js.yml?label=test%20cli&logo=github)](https://github.com/tauri-apps/tauri/actions/workflows/test-cli-js.yml) +[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftauri-apps%2Ftauri?ref=badge_shield) +[![Chat Server](https://img.shields.io/badge/chat-discord-7289da.svg)](https://discord.gg/SpmNs4S) +[![website](https://img.shields.io/badge/website-tauri.app-purple.svg)](https://tauri.app) +[![https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg](https://good-labs.github.io/greater-good-affirmation/assets/images/badge.svg)](https://good-labs.github.io/greater-good-affirmation) +[![support](https://img.shields.io/badge/sponsor-Open%20Collective-blue.svg)](https://opencollective.com/tauri) + +| Component | Version | +| --------------- | ----------------------------------------------------- | +| @tauri-apps/cli | ![](https://img.shields.io/npm/v/@tauri-apps/cli.svg) | + +## About Tauri + +Tauri is a polyglot and generic system that is very composable and allows engineers to make a wide variety of applications. It is used for building applications for Desktop Computers using a combination of Rust tools and HTML rendered in a Webview. Apps built with Tauri can ship with any number of pieces of an optional JS API / Rust API so that webviews can control the system via message passing. In fact, developers can extend the default API with their own functionality and bridge the Webview and Rust-based backend easily. + +Tauri apps can have custom menus and have tray-type interfaces. They can be updated, and are managed by the user's operating system as expected. They are very small, because they use the system's webview. They do not ship a runtime, since the final binary is compiled from rust. This makes the reversing of Tauri apps not a trivial task. + +## This module + +Written in Typescript and packaged such that it can be used with `npm`, `pnpm`, `yarn`, and `bun`, this library provides a node.js runner for common tasks when using Tauri, like `pnpm tauri dev`. For the most part it is a wrapper around [tauri-cli](https://github.com/tauri-apps/tauri/blob/dev/crates/tauri-cli). + +To learn more about the details of how all of these pieces fit together, please consult this [ARCHITECTURE.md](https://github.com/tauri-apps/tauri/blob/dev/ARCHITECTURE.md) document. + +## Installation + +The preferred method is to install this module locally as a development dependency: + +``` +$ pnpm add -D @tauri-apps/cli +$ yarn add -D @tauri-apps/cli +$ npm add -D @tauri-apps/cli +``` + +## Semver + +**tauri** is following [Semantic Versioning 2.0](https://semver.org/). + +## Licenses + +Code: (c) 2019 - 2021 - The Tauri Programme within The Commons Conservancy. + +MIT or MIT/Apache 2.0 where applicable. + +Logo: CC-BY-NC-ND + +- Original Tauri Logo Designs by [Daniel Thompson-Yvetot](https://github.com/nothingismagick) and [Guillaume Chau](https://github.com/akryum) diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/append-headers.js b/tools/join-backups/node_modules/@tauri-apps/cli/append-headers.js new file mode 100644 index 0000000..22c6768 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/append-headers.js @@ -0,0 +1,15 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +const HEADERS = `// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT` + +const fs = require('fs') + +for (const file of ['index.js', 'index.d.ts']) { + const content = fs.readFileSync(file, 'utf8') + const newContent = `${HEADERS}\n\n${content}` + fs.writeFileSync(file, newContent, 'utf8') +} diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/config.schema.json b/tools/join-backups/node_modules/@tauri-apps/cli/config.schema.json new file mode 100644 index 0000000..4ccf34d --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/config.schema.json @@ -0,0 +1,3846 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "$id": "https://schema.tauri.app/config/2.9.5", + "title": "Config", + "description": "The Tauri configuration object.\n It is read from a file where you can define your frontend assets,\n configure the bundler and define a tray icon.\n\n The configuration file is generated by the\n [`tauri init`](https://v2.tauri.app/reference/cli/#init) command that lives in\n your Tauri application source directory (src-tauri).\n\n Once generated, you may modify it at will to customize your Tauri application.\n\n ## File Formats\n\n By default, the configuration is defined as a JSON file named `tauri.conf.json`.\n\n Tauri also supports JSON5 and TOML files via the `config-json5` and `config-toml` Cargo features, respectively.\n The JSON5 file name must be either `tauri.conf.json` or `tauri.conf.json5`.\n The TOML file name is `Tauri.toml`.\n\n ## Platform-Specific Configuration\n\n In addition to the default configuration file, Tauri can\n read a platform-specific configuration from `tauri.linux.conf.json`,\n `tauri.windows.conf.json`, `tauri.macos.conf.json`, `tauri.android.conf.json` and `tauri.ios.conf.json`\n (or `Tauri.linux.toml`, `Tauri.windows.toml`, `Tauri.macos.toml`, `Tauri.android.toml` and `Tauri.ios.toml` if the `Tauri.toml` format is used),\n which gets merged with the main configuration object.\n\n ## Configuration Structure\n\n The configuration is composed of the following objects:\n\n - [`app`](#appconfig): The Tauri configuration\n - [`build`](#buildconfig): The build configuration\n - [`bundle`](#bundleconfig): The bundle configurations\n - [`plugins`](#pluginconfig): The plugins configuration\n\n Example tauri.config.json file:\n\n ```json\n {\n \"productName\": \"tauri-app\",\n \"version\": \"0.1.0\",\n \"build\": {\n \"beforeBuildCommand\": \"\",\n \"beforeDevCommand\": \"\",\n \"devUrl\": \"http://localhost:3000\",\n \"frontendDist\": \"../dist\"\n },\n \"app\": {\n \"security\": {\n \"csp\": null\n },\n \"windows\": [\n {\n \"fullscreen\": false,\n \"height\": 600,\n \"resizable\": true,\n \"title\": \"Tauri App\",\n \"width\": 800\n }\n ]\n },\n \"bundle\": {},\n \"plugins\": {}\n }\n ```", + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "$schema": { + "description": "The JSON schema for the Tauri config.", + "type": [ + "string", + "null" + ] + }, + "productName": { + "description": "App name.", + "type": [ + "string", + "null" + ], + "pattern": "^[^/\\:*?\"<>|]+$" + }, + "mainBinaryName": { + "description": "Overrides app's main binary filename.\n\n By default, Tauri uses the output binary from `cargo`, by setting this, we will rename that binary in `tauri-cli`'s\n `tauri build` command, and target `tauri bundle` to it\n\n If possible, change the [`package name`] or set the [`name field`] instead,\n and if that's not enough and you're using nightly, consider using the [`different-binary-name`] feature instead\n\n Note: this config should not include the binary extension (e.g. `.exe`), we'll add that for you\n\n [`package name`]: https://doc.rust-lang.org/cargo/reference/manifest.html#the-name-field\n [`name field`]: https://doc.rust-lang.org/cargo/reference/cargo-targets.html#the-name-field\n [`different-binary-name`]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#different-binary-name", + "type": [ + "string", + "null" + ] + }, + "version": { + "description": "App version. It is a semver version number or a path to a `package.json` file containing the `version` field.\n\n If removed the version number from `Cargo.toml` is used.\n It's recommended to manage the app versioning in the Tauri config.\n\n ## Platform-specific\n\n - **macOS**: Translates to the bundle's CFBundleShortVersionString property and is used as the default CFBundleVersion.\n You can set an specific bundle version using [`bundle > macOS > bundleVersion`](MacConfig::bundle_version).\n - **iOS**: Translates to the bundle's CFBundleShortVersionString property and is used as the default CFBundleVersion.\n You can set an specific bundle version using [`bundle > iOS > bundleVersion`](IosConfig::bundle_version).\n The `tauri ios build` CLI command has a `--build-number ` option that lets you append a build number to the app version.\n - **Android**: By default version 1.0 is used. You can set a version code using [`bundle > android > versionCode`](AndroidConfig::version_code).\n\n By default version 1.0 is used on Android.", + "type": [ + "string", + "null" + ] + }, + "identifier": { + "description": "The application identifier in reverse domain name notation (e.g. `com.tauri.example`).\n This string must be unique across applications since it is used in system configurations like\n the bundle ID and path to the webview data directory.\n This string must contain only alphanumeric characters (A-Z, a-z, and 0-9), hyphens (-),\n and periods (.).", + "type": "string" + }, + "app": { + "description": "The App configuration.", + "default": { + "enableGTKAppId": false, + "macOSPrivateApi": false, + "security": { + "assetProtocol": { + "enable": false, + "scope": [] + }, + "capabilities": [], + "dangerousDisableAssetCspModification": false, + "freezePrototype": false, + "pattern": { + "use": "brownfield" + } + }, + "windows": [], + "withGlobalTauri": false + }, + "allOf": [ + { + "$ref": "#/definitions/AppConfig" + } + ] + }, + "build": { + "description": "The build configuration.", + "default": { + "additionalWatchFolders": [], + "removeUnusedCommands": false + }, + "allOf": [ + { + "$ref": "#/definitions/BuildConfig" + } + ] + }, + "bundle": { + "description": "The bundler configuration.", + "default": { + "active": false, + "android": { + "autoIncrementVersionCode": false, + "minSdkVersion": 24 + }, + "createUpdaterArtifacts": false, + "iOS": { + "minimumSystemVersion": "14.0" + }, + "icon": [], + "linux": { + "appimage": { + "bundleMediaFramework": false, + "files": {} + }, + "deb": { + "files": {} + }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + } + }, + "macOS": { + "dmg": { + "appPosition": { + "x": 180, + "y": 170 + }, + "applicationFolderPosition": { + "x": 480, + "y": 170 + }, + "windowSize": { + "height": 400, + "width": 660 + } + }, + "files": {}, + "hardenedRuntime": true, + "minimumSystemVersion": "10.13" + }, + "targets": "all", + "useLocalToolsDir": false, + "windows": { + "allowDowngrades": true, + "certificateThumbprint": null, + "digestAlgorithm": null, + "nsis": null, + "signCommand": null, + "timestampUrl": null, + "tsp": false, + "webviewInstallMode": { + "silent": true, + "type": "downloadBootstrapper" + }, + "wix": null + } + }, + "allOf": [ + { + "$ref": "#/definitions/BundleConfig" + } + ] + }, + "plugins": { + "description": "The plugins config.", + "default": {}, + "allOf": [ + { + "$ref": "#/definitions/PluginConfig" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "AppConfig": { + "description": "The App configuration object.\n\n See more: ", + "type": "object", + "properties": { + "windows": { + "description": "The app windows configuration.\n\n ## Example:\n\n To create a window at app startup\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n If not specified, the window's label (its identifier) defaults to \"main\",\n you can use this label to get the window through\n `app.get_webview_window` in Rust or `WebviewWindow.getByLabel` in JavaScript\n\n When working with multiple windows, each window will need an unique label\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"label\": \"main\", \"width\": 800, \"height\": 600 },\n { \"label\": \"secondary\", \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n You can also set `create` to false and use this config through the Rust APIs\n\n ```json\n {\n \"app\": {\n \"windows\": [\n { \"create\": false, \"width\": 800, \"height\": 600 }\n ]\n }\n }\n ```\n\n and use it like this\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/WindowConfig" + } + }, + "security": { + "description": "Security configuration.", + "default": { + "assetProtocol": { + "enable": false, + "scope": [] + }, + "capabilities": [], + "dangerousDisableAssetCspModification": false, + "freezePrototype": false, + "pattern": { + "use": "brownfield" + } + }, + "allOf": [ + { + "$ref": "#/definitions/SecurityConfig" + } + ] + }, + "trayIcon": { + "description": "Configuration for app tray icon.", + "anyOf": [ + { + "$ref": "#/definitions/TrayIconConfig" + }, + { + "type": "null" + } + ] + }, + "macOSPrivateApi": { + "description": "MacOS private API configuration. Enables the transparent background API and sets the `fullScreenEnabled` preference to `true`.", + "default": false, + "type": "boolean" + }, + "withGlobalTauri": { + "description": "Whether we should inject the Tauri API on `window.__TAURI__` or not.", + "default": false, + "type": "boolean" + }, + "enableGTKAppId": { + "description": "If set to true \"identifier\" will be set as GTK app ID (on systems that use GTK).", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "WindowConfig": { + "description": "The window configuration object.\n\n See more: ", + "type": "object", + "properties": { + "label": { + "description": "The window identifier. It must be alphanumeric.", + "default": "main", + "type": "string" + }, + "create": { + "description": "Whether Tauri should create this window at app startup or not.\n\n When this is set to `false` you must manually grab the config object via `app.config().app.windows`\n and create it with [`WebviewWindowBuilder::from_config`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.from_config).\n\n ## Example:\n\n ```rust\n tauri::Builder::default()\n .setup(|app| {\n tauri::WebviewWindowBuilder::from_config(app.handle(), app.config().app.windows[0])?.build()?;\n Ok(())\n });\n ```", + "default": true, + "type": "boolean" + }, + "url": { + "description": "The window webview URL.", + "default": "index.html", + "allOf": [ + { + "$ref": "#/definitions/WebviewUrl" + } + ] + }, + "userAgent": { + "description": "The user agent for the webview", + "type": [ + "string", + "null" + ] + }, + "dragDropEnabled": { + "description": "Whether the drag and drop is enabled or not on the webview. By default it is enabled.\n\n Disabling it is required to use HTML5 drag and drop on the frontend on Windows.", + "default": true, + "type": "boolean" + }, + "center": { + "description": "Whether or not the window starts centered or not.", + "default": false, + "type": "boolean" + }, + "x": { + "description": "The horizontal position of the window's top left corner", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "y": { + "description": "The vertical position of the window's top left corner", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "width": { + "description": "The window width.", + "default": 800.0, + "type": "number", + "format": "double" + }, + "height": { + "description": "The window height.", + "default": 600.0, + "type": "number", + "format": "double" + }, + "minWidth": { + "description": "The min window width.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "minHeight": { + "description": "The min window height.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "maxWidth": { + "description": "The max window width.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "maxHeight": { + "description": "The max window height.", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "preventOverflow": { + "description": "Whether or not to prevent the window from overflowing the workarea\n\n ## Platform-specific\n\n - **iOS / Android:** Unsupported.", + "anyOf": [ + { + "$ref": "#/definitions/PreventOverflowConfig" + }, + { + "type": "null" + } + ] + }, + "resizable": { + "description": "Whether the window is resizable or not. When resizable is set to false, native window's maximize button is automatically disabled.", + "default": true, + "type": "boolean" + }, + "maximizable": { + "description": "Whether the window's native maximize button is enabled or not.\n If resizable is set to false, this setting is ignored.\n\n ## Platform-specific\n\n - **macOS:** Disables the \"zoom\" button in the window titlebar, which is also used to enter fullscreen mode.\n - **Linux / iOS / Android:** Unsupported.", + "default": true, + "type": "boolean" + }, + "minimizable": { + "description": "Whether the window's native minimize button is enabled or not.\n\n ## Platform-specific\n\n - **Linux / iOS / Android:** Unsupported.", + "default": true, + "type": "boolean" + }, + "closable": { + "description": "Whether the window's native close button is enabled or not.\n\n ## Platform-specific\n\n - **Linux:** \"GTK+ will do its best to convince the window manager not to show a close button.\n Depending on the system, this function may not have any effect when called on a window that is already visible\"\n - **iOS / Android:** Unsupported.", + "default": true, + "type": "boolean" + }, + "title": { + "description": "The window title.", + "default": "Tauri App", + "type": "string" + }, + "fullscreen": { + "description": "Whether the window starts as fullscreen or not.", + "default": false, + "type": "boolean" + }, + "focus": { + "description": "Whether the window will be initially focused or not.", + "default": true, + "type": "boolean" + }, + "focusable": { + "description": "Whether the window will be focusable or not.", + "default": true, + "type": "boolean" + }, + "transparent": { + "description": "Whether the window is transparent or not.\n\n Note that on `macOS` this requires the `macos-private-api` feature flag, enabled under `tauri > macOSPrivateApi`.\n WARNING: Using private APIs on `macOS` prevents your application from being accepted to the `App Store`.", + "default": false, + "type": "boolean" + }, + "maximized": { + "description": "Whether the window is maximized or not.", + "default": false, + "type": "boolean" + }, + "visible": { + "description": "Whether the window is visible or not.", + "default": true, + "type": "boolean" + }, + "decorations": { + "description": "Whether the window should have borders and bars.", + "default": true, + "type": "boolean" + }, + "alwaysOnBottom": { + "description": "Whether the window should always be below other windows.", + "default": false, + "type": "boolean" + }, + "alwaysOnTop": { + "description": "Whether the window should always be on top of other windows.", + "default": false, + "type": "boolean" + }, + "visibleOnAllWorkspaces": { + "description": "Whether the window should be visible on all workspaces or virtual desktops.\n\n ## Platform-specific\n\n - **Windows / iOS / Android:** Unsupported.", + "default": false, + "type": "boolean" + }, + "contentProtected": { + "description": "Prevents the window contents from being captured by other apps.", + "default": false, + "type": "boolean" + }, + "skipTaskbar": { + "description": "If `true`, hides the window icon from the taskbar on Windows and Linux.", + "default": false, + "type": "boolean" + }, + "windowClassname": { + "description": "The name of the window class created on Windows to create the window. **Windows only**.", + "type": [ + "string", + "null" + ] + }, + "theme": { + "description": "The initial window theme. Defaults to the system theme. Only implemented on Windows and macOS 10.14+.", + "anyOf": [ + { + "$ref": "#/definitions/Theme" + }, + { + "type": "null" + } + ] + }, + "titleBarStyle": { + "description": "The style of the macOS title bar.", + "default": "Visible", + "allOf": [ + { + "$ref": "#/definitions/TitleBarStyle" + } + ] + }, + "trafficLightPosition": { + "description": "The position of the window controls on macOS.\n\n Requires titleBarStyle: Overlay and decorations: true.", + "anyOf": [ + { + "$ref": "#/definitions/LogicalPosition" + }, + { + "type": "null" + } + ] + }, + "hiddenTitle": { + "description": "If `true`, sets the window title to be hidden on macOS.", + "default": false, + "type": "boolean" + }, + "acceptFirstMouse": { + "description": "Whether clicking an inactive window also clicks through to the webview on macOS.", + "default": false, + "type": "boolean" + }, + "tabbingIdentifier": { + "description": "Defines the window [tabbing identifier] for macOS.\n\n Windows with matching tabbing identifiers will be grouped together.\n If the tabbing identifier is not set, automatic tabbing will be disabled.\n\n [tabbing identifier]: ", + "type": [ + "string", + "null" + ] + }, + "additionalBrowserArgs": { + "description": "Defines additional browser arguments on Windows. By default wry passes `--disable-features=msWebOOUI,msPdfOOUI,msSmartScreenProtection`\n so if you use this method, you also need to disable these components by yourself if you want.", + "type": [ + "string", + "null" + ] + }, + "shadow": { + "description": "Whether or not the window has shadow.\n\n ## Platform-specific\n\n - **Windows:**\n - `false` has no effect on decorated window, shadow are always ON.\n - `true` will make undecorated window have a 1px white border,\n and on Windows 11, it will have a rounded corners.\n - **Linux:** Unsupported.", + "default": true, + "type": "boolean" + }, + "windowEffects": { + "description": "Window effects.\n\n Requires the window to be transparent.\n\n ## Platform-specific:\n\n - **Windows**: If using decorations or shadows, you may want to try this workaround \n - **Linux**: Unsupported", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectsConfig" + }, + { + "type": "null" + } + ] + }, + "incognito": { + "description": "Whether or not the webview should be launched in incognito mode.\n\n ## Platform-specific:\n\n - **Android**: Unsupported.", + "default": false, + "type": "boolean" + }, + "parent": { + "description": "Sets the window associated with this label to be the parent of the window to be created.\n\n ## Platform-specific\n\n - **Windows**: This sets the passed parent as an owner window to the window to be created.\n From [MSDN owned windows docs](https://docs.microsoft.com/en-us/windows/win32/winmsg/window-features#owned-windows):\n - An owned window is always above its owner in the z-order.\n - The system automatically destroys an owned window when its owner is destroyed.\n - An owned window is hidden when its owner is minimized.\n - **Linux**: This makes the new window transient for parent, see \n - **macOS**: This adds the window as a child of parent, see ", + "type": [ + "string", + "null" + ] + }, + "proxyUrl": { + "description": "The proxy URL for the WebView for all network requests.\n\n Must be either a `http://` or a `socks5://` URL.\n\n ## Platform-specific\n\n - **macOS**: Requires the `macos-proxy` feature flag and only compiles for macOS 14+.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "zoomHotkeysEnabled": { + "description": "Whether page zooming by hotkeys is enabled\n\n ## Platform-specific:\n\n - **Windows**: Controls WebView2's [`IsZoomControlEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2settings?view=webview2-winrt-1.0.2420.47#iszoomcontrolenabled) setting.\n - **MacOS / Linux**: Injects a polyfill that zooms in and out with `ctrl/command` + `-/=`,\n 20% in each step, ranging from 20% to 1000%. Requires `webview:allow-set-webview-zoom` permission\n\n - **Android / iOS**: Unsupported.", + "default": false, + "type": "boolean" + }, + "browserExtensionsEnabled": { + "description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.", + "default": false, + "type": "boolean" + }, + "useHttpsScheme": { + "description": "Sets whether the custom protocols should use `https://.localhost` instead of the default `http://.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.", + "default": false, + "type": "boolean" + }, + "devtools": { + "description": "Enable web inspector which is usually called browser devtools. Enabled by default.\n\n This API works in **debug** builds, but requires `devtools` feature flag to enable it in **release** builds.\n\n ## Platform-specific\n\n - macOS: This will call private functions on **macOS**.\n - Android: Open `chrome://inspect/#devices` in Chrome to get the devtools window. Wry's `WebView` devtools API isn't supported on Android.\n - iOS: Open Safari > Develop > [Your Device Name] > [Your WebView] to get the devtools window.", + "type": [ + "boolean", + "null" + ] + }, + "backgroundColor": { + "description": "Set the window and webview background color.\n\n ## Platform-specific:\n\n - **Windows**: alpha channel is ignored for the window layer.\n - **Windows**: On Windows 7, alpha channel is ignored for the webview layer.\n - **Windows**: On Windows 8 and newer, if alpha channel is not `0`, it will be ignored for the webview layer.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] + }, + "backgroundThrottling": { + "description": "Change the default background throttling behaviour.\n\n By default, browsers use a suspend policy that will throttle timers and even unload\n the whole tab (view) to free resources after roughly 5 minutes when a view became\n minimized or hidden. This will pause all tasks until the documents visibility state\n changes back from hidden to visible by bringing the view back to the foreground.\n\n ## Platform-specific\n\n - **Linux / Windows / Android**: Unsupported. Workarounds like a pending WebLock transaction might suffice.\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n\n see https://github.com/tauri-apps/tauri/issues/5250#issuecomment-2569380578", + "anyOf": [ + { + "$ref": "#/definitions/BackgroundThrottlingPolicy" + }, + { + "type": "null" + } + ] + }, + "javascriptDisabled": { + "description": "Whether we should disable JavaScript code execution on the webview or not.", + "default": false, + "type": "boolean" + }, + "allowLinkPreview": { + "description": "on macOS and iOS there is a link preview on long pressing links, this is enabled by default.\n see https://docs.rs/objc2-web-kit/latest/objc2_web_kit/struct.WKWebView.html#method.allowsLinkPreview", + "default": true, + "type": "boolean" + }, + "disableInputAccessoryView": { + "description": "Allows disabling the input accessory view on iOS.\n\n The accessory view is the view that appears above the keyboard when a text input element is focused.\n It usually displays a view with \"Done\", \"Next\" buttons.", + "default": false, + "type": "boolean" + }, + "dataDirectory": { + "description": "Set a custom path for the webview's data directory (localStorage, cache, etc.) **relative to [`appDataDir()`]/${label}**.\n\n To set absolute paths, use [`WebviewWindowBuilder::data_directory`](https://docs.rs/tauri/2/tauri/webview/struct.WebviewWindowBuilder.html#method.data_directory)\n\n #### Platform-specific:\n\n - **Windows**: WebViews with different values for settings like `additionalBrowserArgs`, `browserExtensionsEnabled` or `scrollBarStyle` must have different data directories.\n - **macOS / iOS**: Unsupported, use `dataStoreIdentifier` instead.\n - **Android**: Unsupported.", + "type": [ + "string", + "null" + ] + }, + "dataStoreIdentifier": { + "description": "Initialize the WebView with a custom data store identifier. This can be seen as a replacement for `dataDirectory` which is unavailable in WKWebView.\n See https://developer.apple.com/documentation/webkit/wkwebsitedatastore/init(foridentifier:)?language=objc\n\n The array must contain 16 u8 numbers.\n\n #### Platform-specific:\n\n - **iOS**: Supported since version 17.0+.\n - **macOS**: Supported since version 14.0+.\n - **Windows / Linux / Android**: Unsupported.", + "type": [ + "array", + "null" + ], + "items": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "maxItems": 16, + "minItems": 16 + }, + "scrollBarStyle": { + "description": "Specifies the native scrollbar style to use with the webview.\n CSS styles that modify the scrollbar are applied on top of the native appearance configured here.\n\n Defaults to `default`, which is the browser default.\n\n ## Platform-specific\n\n - **Windows**:\n - `fluentOverlay` requires WebView2 Runtime version 125.0.2535.41 or higher,\n and does nothing on older versions.\n - This option must be given the same value for all webviews that target the same data directory.\n - **Linux / Android / iOS / macOS**: Unsupported. Only supports `Default` and performs no operation.", + "default": "default", + "allOf": [ + { + "$ref": "#/definitions/ScrollBarStyle" + } + ] + } + }, + "additionalProperties": false + }, + "WebviewUrl": { + "description": "An URL to open on a Tauri webview window.", + "anyOf": [ + { + "description": "An external URL. Must use either the `http` or `https` schemes.", + "type": "string", + "format": "uri" + }, + { + "description": "The path portion of an app URL.\n For instance, to load `tauri://localhost/users/john`,\n you can simply provide `users/john` in this configuration.", + "type": "string" + }, + { + "description": "A custom protocol url, for example, `doom://index.html`", + "type": "string", + "format": "uri" + } + ] + }, + "PreventOverflowConfig": { + "description": "Prevent overflow with a margin", + "anyOf": [ + { + "description": "Enable prevent overflow or not", + "type": "boolean" + }, + { + "description": "Enable prevent overflow with a margin\n so that the window's size + this margin won't overflow the workarea", + "allOf": [ + { + "$ref": "#/definitions/PreventOverflowMargin" + } + ] + } + ] + }, + "PreventOverflowMargin": { + "description": "Enable prevent overflow with a margin\n so that the window's size + this margin won't overflow the workarea", + "type": "object", + "required": [ + "height", + "width" + ], + "properties": { + "width": { + "description": "Horizontal margin in physical unit", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "height": { + "description": "Vertical margin in physical unit", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Theme": { + "description": "System theme.", + "oneOf": [ + { + "description": "Light theme.", + "type": "string", + "enum": [ + "Light" + ] + }, + { + "description": "Dark theme.", + "type": "string", + "enum": [ + "Dark" + ] + } + ] + }, + "TitleBarStyle": { + "description": "How the window title bar should be displayed on macOS.", + "oneOf": [ + { + "description": "A normal title bar.", + "type": "string", + "enum": [ + "Visible" + ] + }, + { + "description": "Makes the title bar transparent, so the window background color is shown instead.\n\n Useful if you don't need to have actual HTML under the title bar. This lets you avoid the caveats of using `TitleBarStyle::Overlay`. Will be more useful when Tauri lets you set a custom window background color.", + "type": "string", + "enum": [ + "Transparent" + ] + }, + { + "description": "Shows the title bar as a transparent overlay over the window's content.\n\n Keep in mind:\n - The height of the title bar is different on different OS versions, which can lead to window the controls and title not being where you don't expect.\n - You need to define a custom drag region to make your window draggable, however due to a limitation you can't drag the window when it's not in focus .\n - The color of the window title depends on the system theme.", + "type": "string", + "enum": [ + "Overlay" + ] + } + ] + }, + "LogicalPosition": { + "description": "Position coordinates struct.", + "type": "object", + "required": [ + "x", + "y" + ], + "properties": { + "x": { + "description": "X coordinate.", + "type": "number", + "format": "double" + }, + "y": { + "description": "Y coordinate.", + "type": "number", + "format": "double" + } + }, + "additionalProperties": false + }, + "WindowEffectsConfig": { + "description": "The window effects configuration object", + "type": "object", + "required": [ + "effects" + ], + "properties": { + "effects": { + "description": "List of Window effects to apply to the Window.\n Conflicting effects will apply the first one and ignore the rest.", + "type": "array", + "items": { + "$ref": "#/definitions/WindowEffect" + } + }, + "state": { + "description": "Window effect state **macOS Only**", + "anyOf": [ + { + "$ref": "#/definitions/WindowEffectState" + }, + { + "type": "null" + } + ] + }, + "radius": { + "description": "Window effect corner radius **macOS Only**", + "type": [ + "number", + "null" + ], + "format": "double" + }, + "color": { + "description": "Window effect color. Affects [`WindowEffect::Blur`] and [`WindowEffect::Acrylic`] only\n on Windows 10 v1903+. Doesn't have any effect on Windows 7 or Windows 11.", + "anyOf": [ + { + "$ref": "#/definitions/Color" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "WindowEffect": { + "description": "Platform-specific window effects", + "oneOf": [ + { + "description": "A default material appropriate for the view's effectiveAppearance. **macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "appearanceBased" + ] + }, + { + "description": "**macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "light" + ] + }, + { + "description": "**macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "dark" + ] + }, + { + "description": "**macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "mediumLight" + ] + }, + { + "description": "**macOS 10.14-**", + "deprecated": true, + "type": "string", + "enum": [ + "ultraDark" + ] + }, + { + "description": "**macOS 10.10+**", + "type": "string", + "enum": [ + "titlebar" + ] + }, + { + "description": "**macOS 10.10+**", + "type": "string", + "enum": [ + "selection" + ] + }, + { + "description": "**macOS 10.11+**", + "type": "string", + "enum": [ + "menu" + ] + }, + { + "description": "**macOS 10.11+**", + "type": "string", + "enum": [ + "popover" + ] + }, + { + "description": "**macOS 10.11+**", + "type": "string", + "enum": [ + "sidebar" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "headerView" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "sheet" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "windowBackground" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "hudWindow" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "fullScreenUI" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "tooltip" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "contentBackground" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "underWindowBackground" + ] + }, + { + "description": "**macOS 10.14+**", + "type": "string", + "enum": [ + "underPageBackground" + ] + }, + { + "description": "Mica effect that matches the system dark preference **Windows 11 Only**", + "type": "string", + "enum": [ + "mica" + ] + }, + { + "description": "Mica effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**", + "type": "string", + "enum": [ + "micaDark" + ] + }, + { + "description": "Mica effect with light mode **Windows 11 Only**", + "type": "string", + "enum": [ + "micaLight" + ] + }, + { + "description": "Tabbed effect that matches the system dark preference **Windows 11 Only**", + "type": "string", + "enum": [ + "tabbed" + ] + }, + { + "description": "Tabbed effect with dark mode but only if dark mode is enabled on the system **Windows 11 Only**", + "type": "string", + "enum": [ + "tabbedDark" + ] + }, + { + "description": "Tabbed effect with light mode **Windows 11 Only**", + "type": "string", + "enum": [ + "tabbedLight" + ] + }, + { + "description": "**Windows 7/10/11(22H1) Only**\n\n ## Notes\n\n This effect has bad performance when resizing/dragging the window on Windows 11 build 22621.", + "type": "string", + "enum": [ + "blur" + ] + }, + { + "description": "**Windows 10/11 Only**\n\n ## Notes\n\n This effect has bad performance when resizing/dragging the window on Windows 10 v1903+ and Windows 11 build 22000.", + "type": "string", + "enum": [ + "acrylic" + ] + } + ] + }, + "WindowEffectState": { + "description": "Window effect state **macOS only**\n\n ", + "oneOf": [ + { + "description": "Make window effect state follow the window's active state", + "type": "string", + "enum": [ + "followsWindowActiveState" + ] + }, + { + "description": "Make window effect state always active", + "type": "string", + "enum": [ + "active" + ] + }, + { + "description": "Make window effect state always inactive", + "type": "string", + "enum": [ + "inactive" + ] + } + ] + }, + "Color": { + "anyOf": [ + { + "description": "Color hex string, for example: #fff, #ffffff, or #ffffffff.", + "type": "string", + "pattern": "^#?([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{8})$" + }, + { + "description": "Array of RGB colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 3, + "minItems": 3 + }, + { + "description": "Array of RGBA colors. Each value has minimum of 0 and maximum of 255.", + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + ], + "maxItems": 4, + "minItems": 4 + }, + { + "description": "Object of red, green, blue, alpha color values. Each value has minimum of 0 and maximum of 255.", + "type": "object", + "required": [ + "blue", + "green", + "red" + ], + "properties": { + "red": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "green": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "blue": { + "type": "integer", + "format": "uint8", + "minimum": 0.0 + }, + "alpha": { + "default": 255, + "type": "integer", + "format": "uint8", + "minimum": 0.0 + } + } + } + ] + }, + "BackgroundThrottlingPolicy": { + "description": "Background throttling policy.", + "oneOf": [ + { + "description": "A policy where background throttling is disabled", + "type": "string", + "enum": [ + "disabled" + ] + }, + { + "description": "A policy where a web view that's not in a window fully suspends tasks. This is usually the default behavior in case no policy is set.", + "type": "string", + "enum": [ + "suspend" + ] + }, + { + "description": "A policy where a web view that's not in a window limits processing, but does not fully suspend tasks.", + "type": "string", + "enum": [ + "throttle" + ] + } + ] + }, + "ScrollBarStyle": { + "description": "The scrollbar style to use in the webview.\n\n ## Platform-specific\n\n - **Windows**: This option must be given the same value for all webviews that target the same data directory.", + "oneOf": [ + { + "description": "The scrollbar style to use in the webview.", + "type": "string", + "enum": [ + "default" + ] + }, + { + "description": "Fluent UI style overlay scrollbars. **Windows Only**\n\n Requires WebView2 Runtime version 125.0.2535.41 or higher, does nothing on older versions,\n see https://learn.microsoft.com/en-us/microsoft-edge/webview2/release-notes/?tabs=dotnetcsharp#10253541", + "type": "string", + "enum": [ + "fluentOverlay" + ] + } + ] + }, + "SecurityConfig": { + "description": "Security configuration.\n\n See more: ", + "type": "object", + "properties": { + "csp": { + "description": "The Content Security Policy that will be injected on all HTML files on the built application.\n If [`dev_csp`](#SecurityConfig.devCsp) is not specified, this value is also injected on dev.\n\n This is a really important part of the configuration since it helps you ensure your WebView is secured.\n See .", + "anyOf": [ + { + "$ref": "#/definitions/Csp" + }, + { + "type": "null" + } + ] + }, + "devCsp": { + "description": "The Content Security Policy that will be injected on all HTML files on development.\n\n This is a really important part of the configuration since it helps you ensure your WebView is secured.\n See .", + "anyOf": [ + { + "$ref": "#/definitions/Csp" + }, + { + "type": "null" + } + ] + }, + "freezePrototype": { + "description": "Freeze the `Object.prototype` when using the custom protocol.", + "default": false, + "type": "boolean" + }, + "dangerousDisableAssetCspModification": { + "description": "Disables the Tauri-injected CSP sources.\n\n At compile time, Tauri parses all the frontend assets and changes the Content-Security-Policy\n to only allow loading of your own scripts and styles by injecting nonce and hash sources.\n This stricts your CSP, which may introduce issues when using along with other flexing sources.\n\n This configuration option allows both a boolean and a list of strings as value.\n A boolean instructs Tauri to disable the injection for all CSP injections,\n and a list of strings indicates the CSP directives that Tauri cannot inject.\n\n **WARNING:** Only disable this if you know what you are doing and have properly configured the CSP.\n Your application might be vulnerable to XSS attacks without this Tauri protection.", + "default": false, + "allOf": [ + { + "$ref": "#/definitions/DisabledCspModificationKind" + } + ] + }, + "assetProtocol": { + "description": "Custom protocol config.", + "default": { + "enable": false, + "scope": [] + }, + "allOf": [ + { + "$ref": "#/definitions/AssetProtocolConfig" + } + ] + }, + "pattern": { + "description": "The pattern to use.", + "default": { + "use": "brownfield" + }, + "allOf": [ + { + "$ref": "#/definitions/PatternKind" + } + ] + }, + "capabilities": { + "description": "List of capabilities that are enabled on the application.\n\n By default (not set or empty list), all capability files from `./capabilities/` are included,\n by setting values in this entry, you have fine grained control over which capabilities are included\n\n You can either reference a capability file defined in `./capabilities/` with its identifier or inline a [`Capability`]\n\n ### Example\n\n ```json\n {\n \"app\": {\n \"capabilities\": [\n \"main-window\",\n {\n \"identifier\": \"drag-window\",\n \"permissions\": [\"core:window:allow-start-dragging\"]\n }\n ]\n }\n }\n ```", + "default": [], + "type": "array", + "items": { + "$ref": "#/definitions/CapabilityEntry" + } + }, + "headers": { + "description": "The headers, which are added to every http response from tauri to the web view\n This doesn't include IPC Messages and error responses", + "anyOf": [ + { + "$ref": "#/definitions/HeaderConfig" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "Csp": { + "description": "A Content-Security-Policy definition.\n See .", + "anyOf": [ + { + "description": "The entire CSP policy in a single text string.", + "type": "string" + }, + { + "description": "An object mapping a directive with its sources values as a list of strings.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/CspDirectiveSources" + } + } + ] + }, + "CspDirectiveSources": { + "description": "A Content-Security-Policy directive source list.\n See .", + "anyOf": [ + { + "description": "An inline list of CSP sources. Same as [`Self::List`], but concatenated with a space separator.", + "type": "string" + }, + { + "description": "A list of CSP sources. The collection will be concatenated with a space separator for the CSP string.", + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "DisabledCspModificationKind": { + "description": "The possible values for the `dangerous_disable_asset_csp_modification` config option.", + "anyOf": [ + { + "description": "If `true`, disables all CSP modification.\n `false` is the default value and it configures Tauri to control the CSP.", + "type": "boolean" + }, + { + "description": "Disables the given list of CSP directives modifications.", + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "AssetProtocolConfig": { + "description": "Config for the asset custom protocol.\n\n See more: ", + "type": "object", + "properties": { + "scope": { + "description": "The access scope for the asset protocol.", + "default": [], + "allOf": [ + { + "$ref": "#/definitions/FsScope" + } + ] + }, + "enable": { + "description": "Enables the asset protocol.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "FsScope": { + "description": "Protocol scope definition.\n It is a list of glob patterns that restrict the API access from the webview.\n\n Each pattern can start with a variable that resolves to a system base directory.\n The variables are: `$AUDIO`, `$CACHE`, `$CONFIG`, `$DATA`, `$LOCALDATA`, `$DESKTOP`,\n `$DOCUMENT`, `$DOWNLOAD`, `$EXE`, `$FONT`, `$HOME`, `$PICTURE`, `$PUBLIC`, `$RUNTIME`,\n `$TEMPLATE`, `$VIDEO`, `$RESOURCE`, `$TEMP`,\n `$APPCONFIG`, `$APPDATA`, `$APPLOCALDATA`, `$APPCACHE`, `$APPLOG`.", + "anyOf": [ + { + "description": "A list of paths that are allowed by this scope.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "A complete scope configuration.", + "type": "object", + "properties": { + "allow": { + "description": "A list of paths that are allowed by this scope.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "deny": { + "description": "A list of paths that are not allowed by this scope.\n This gets precedence over the [`Self::Scope::allow`] list.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "requireLiteralLeadingDot": { + "description": "Whether or not paths that contain components that start with a `.`\n will require that `.` appears literally in the pattern; `*`, `?`, `**`,\n or `[...]` will not match. This is useful because such files are\n conventionally considered hidden on Unix systems and it might be\n desirable to skip them when listing files.\n\n Defaults to `true` on Unix systems and `false` on Windows", + "type": [ + "boolean", + "null" + ] + } + } + } + ] + }, + "PatternKind": { + "description": "The application pattern.", + "oneOf": [ + { + "description": "Brownfield pattern.", + "type": "object", + "required": [ + "use" + ], + "properties": { + "use": { + "type": "string", + "enum": [ + "brownfield" + ] + } + } + }, + { + "description": "Isolation pattern. Recommended for security purposes.", + "type": "object", + "required": [ + "options", + "use" + ], + "properties": { + "use": { + "type": "string", + "enum": [ + "isolation" + ] + }, + "options": { + "type": "object", + "required": [ + "dir" + ], + "properties": { + "dir": { + "description": "The dir containing the index.html file that contains the secure isolation application.", + "type": "string" + } + } + } + } + } + ] + }, + "CapabilityEntry": { + "description": "A capability entry which can be either an inlined capability or a reference to a capability defined on its own file.", + "anyOf": [ + { + "description": "An inlined capability.", + "allOf": [ + { + "$ref": "#/definitions/Capability" + } + ] + }, + { + "description": "Reference to a capability identifier.", + "type": "string" + } + ] + }, + "Capability": { + "description": "A grouping and boundary mechanism developers can use to isolate access to the IPC layer.\n\n It controls application windows' and webviews' fine grained access\n to the Tauri core, application, or plugin commands.\n If a webview or its window is not matching any capability then it has no access to the IPC layer at all.\n\n This can be done to create groups of windows, based on their required system access, which can reduce\n impact of frontend vulnerabilities in less privileged windows.\n Windows can be added to a capability by exact name (e.g. `main-window`) or glob patterns like `*` or `admin-*`.\n A Window can have none, one, or multiple associated capabilities.\n\n ## Example\n\n ```json\n {\n \"identifier\": \"main-user-files-write\",\n \"description\": \"This capability allows the `main` window on macOS and Windows access to `filesystem` write related commands and `dialog` commands to enable programmatic access to files selected by the user.\",\n \"windows\": [\n \"main\"\n ],\n \"permissions\": [\n \"core:default\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n },\n ],\n \"platforms\": [\"macOS\",\"windows\"]\n }\n ```", + "type": "object", + "required": [ + "identifier", + "permissions" + ], + "properties": { + "identifier": { + "description": "Identifier of the capability.\n\n ## Example\n\n `main-user-files-write`", + "type": "string" + }, + "description": { + "description": "Description of what the capability is intended to allow on associated windows.\n\n It should contain a description of what the grouped permissions should allow.\n\n ## Example\n\n This capability allows the `main` window access to `filesystem` write related\n commands and `dialog` commands to enable programmatic access to files selected by the user.", + "default": "", + "type": "string" + }, + "remote": { + "description": "Configure remote URLs that can use the capability permissions.\n\n This setting is optional and defaults to not being set, as our\n default use case is that the content is served from our local application.\n\n :::caution\n Make sure you understand the security implications of providing remote\n sources with local system access.\n :::\n\n ## Example\n\n ```json\n {\n \"urls\": [\"https://*.mydomain.dev\"]\n }\n ```", + "anyOf": [ + { + "$ref": "#/definitions/CapabilityRemote" + }, + { + "type": "null" + } + ] + }, + "local": { + "description": "Whether this capability is enabled for local app URLs or not. Defaults to `true`.", + "default": true, + "type": "boolean" + }, + "windows": { + "description": "List of windows that are affected by this capability. Can be a glob pattern.\n\n If a window label matches any of the patterns in this list,\n the capability will be enabled on all the webviews of that window,\n regardless of the value of [`Self::webviews`].\n\n On multiwebview windows, prefer specifying [`Self::webviews`] and omitting [`Self::windows`]\n for a fine grained access control.\n\n ## Example\n\n `[\"main\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "webviews": { + "description": "List of webviews that are affected by this capability. Can be a glob pattern.\n\n The capability will be enabled on all the webviews\n whose label matches any of the patterns in this list,\n regardless of whether the webview's window label matches a pattern in [`Self::windows`].\n\n ## Example\n\n `[\"sub-webview-one\", \"sub-webview-two\"]`", + "type": "array", + "items": { + "type": "string" + } + }, + "permissions": { + "description": "List of permissions attached to this capability.\n\n Must include the plugin name as prefix in the form of `${plugin-name}:${permission-name}`.\n For commands directly implemented in the application itself only `${permission-name}`\n is required.\n\n ## Example\n\n ```json\n [\n \"core:default\",\n \"shell:allow-open\",\n \"dialog:open\",\n {\n \"identifier\": \"fs:allow-write-text-file\",\n \"allow\": [{ \"path\": \"$HOME/test.txt\" }]\n }\n ]\n ```", + "type": "array", + "items": { + "$ref": "#/definitions/PermissionEntry" + }, + "uniqueItems": true + }, + "platforms": { + "description": "Limit which target platforms this capability applies to.\n\n By default all platforms are targeted.\n\n ## Example\n\n `[\"macOS\",\"windows\"]`", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Target" + } + } + } + }, + "CapabilityRemote": { + "description": "Configuration for remote URLs that are associated with the capability.", + "type": "object", + "required": [ + "urls" + ], + "properties": { + "urls": { + "description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).\n\n ## Examples\n\n - \"https://*.mydomain.dev\": allows subdomains of mydomain.dev\n - \"https://mydomain.dev/api/*\": allows any subpath of mydomain.dev/api", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PermissionEntry": { + "description": "An entry for a permission value in a [`Capability`] can be either a raw permission [`Identifier`]\n or an object that references a permission and extends its scope.", + "anyOf": [ + { + "description": "Reference a permission or permission set by identifier.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + { + "description": "Reference a permission or permission set by identifier and extends its scope.", + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "identifier": { + "description": "Identifier of the permission or permission set.", + "allOf": [ + { + "$ref": "#/definitions/Identifier" + } + ] + }, + "allow": { + "description": "Data that defines what is allowed by the scope.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + }, + "deny": { + "description": "Data that defines what is denied by the scope. This should be prioritized by validation logic.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/Value" + } + } + } + } + ] + }, + "Identifier": { + "type": "string" + }, + "Value": { + "description": "All supported ACL values.", + "anyOf": [ + { + "description": "Represents a null JSON value.", + "type": "null" + }, + { + "description": "Represents a [`bool`].", + "type": "boolean" + }, + { + "description": "Represents a valid ACL [`Number`].", + "allOf": [ + { + "$ref": "#/definitions/Number" + } + ] + }, + { + "description": "Represents a [`String`].", + "type": "string" + }, + { + "description": "Represents a list of other [`Value`]s.", + "type": "array", + "items": { + "$ref": "#/definitions/Value" + } + }, + { + "description": "Represents a map of [`String`] keys to [`Value`]s.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/Value" + } + } + ] + }, + "Number": { + "description": "A valid ACL number.", + "anyOf": [ + { + "description": "Represents an [`i64`].", + "type": "integer", + "format": "int64" + }, + { + "description": "Represents a [`f64`].", + "type": "number", + "format": "double" + } + ] + }, + "Target": { + "description": "Platform target.", + "oneOf": [ + { + "description": "MacOS.", + "type": "string", + "enum": [ + "macOS" + ] + }, + { + "description": "Windows.", + "type": "string", + "enum": [ + "windows" + ] + }, + { + "description": "Linux.", + "type": "string", + "enum": [ + "linux" + ] + }, + { + "description": "Android.", + "type": "string", + "enum": [ + "android" + ] + }, + { + "description": "iOS.", + "type": "string", + "enum": [ + "iOS" + ] + } + ] + }, + "HeaderConfig": { + "description": "A struct, where the keys are some specific http header names.\n\n If the values to those keys are defined, then they will be send as part of a response message.\n This does not include error messages and ipc messages\n\n ## Example configuration\n ```javascript\n {\n //..\n app:{\n //..\n security: {\n headers: {\n \"Cross-Origin-Opener-Policy\": \"same-origin\",\n \"Cross-Origin-Embedder-Policy\": \"require-corp\",\n \"Timing-Allow-Origin\": [\n \"https://developer.mozilla.org\",\n \"https://example.com\",\n ],\n \"Access-Control-Expose-Headers\": \"Tauri-Custom-Header\",\n \"Tauri-Custom-Header\": {\n \"key1\": \"'value1' 'value2'\",\n \"key2\": \"'value3'\"\n }\n },\n csp: \"default-src 'self'; connect-src ipc: http://ipc.localhost\",\n }\n //..\n }\n //..\n }\n ```\n In this example `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` are set to allow for the use of [`SharedArrayBuffer`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer).\n The result is, that those headers are then set on every response sent via the `get_response` function in crates/tauri/src/protocol/tauri.rs.\n The Content-Security-Policy header is defined separately, because it is also handled separately.\n\n For the helloworld example, this config translates into those response headers:\n ```http\n access-control-allow-origin: http://tauri.localhost\n access-control-expose-headers: Tauri-Custom-Header\n content-security-policy: default-src 'self'; connect-src ipc: http://ipc.localhost; script-src 'self' 'sha256-Wjjrs6qinmnr+tOry8x8PPwI77eGpUFR3EEGZktjJNs='\n content-type: text/html\n cross-origin-embedder-policy: require-corp\n cross-origin-opener-policy: same-origin\n tauri-custom-header: key1 'value1' 'value2'; key2 'value3'\n timing-allow-origin: https://developer.mozilla.org, https://example.com\n ```\n Since the resulting header values are always 'string-like'. So depending on the what data type the HeaderSource is, they need to be converted.\n - `String`(JS/Rust): stay the same for the resulting header value\n - `Array`(JS)/`Vec\\`(Rust): Item are joined by \", \" for the resulting header value\n - `Object`(JS)/ `Hashmap\\`(Rust): Items are composed from: key + space + value. Item are then joined by \"; \" for the resulting header value", + "type": "object", + "properties": { + "Access-Control-Allow-Credentials": { + "description": "The Access-Control-Allow-Credentials response header tells browsers whether the\n server allows cross-origin HTTP requests to include credentials.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Headers": { + "description": "The Access-Control-Allow-Headers response header is used in response\n to a preflight request which includes the Access-Control-Request-Headers\n to indicate which HTTP headers can be used during the actual request.\n\n This header is required if the request has an Access-Control-Request-Headers header.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Allow-Methods": { + "description": "The Access-Control-Allow-Methods response header specifies one or more methods\n allowed when accessing a resource in response to a preflight request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Expose-Headers": { + "description": "The Access-Control-Expose-Headers response header allows a server to indicate\n which response headers should be made available to scripts running in the browser,\n in response to a cross-origin request.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Access-Control-Max-Age": { + "description": "The Access-Control-Max-Age response header indicates how long the results of a\n preflight request (that is the information contained in the\n Access-Control-Allow-Methods and Access-Control-Allow-Headers headers) can\n be cached.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Embedder-Policy": { + "description": "The HTTP Cross-Origin-Embedder-Policy (COEP) response header configures embedding\n cross-origin resources into the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Opener-Policy": { + "description": "The HTTP Cross-Origin-Opener-Policy (COOP) response header allows you to ensure a\n top-level document does not share a browsing context group with cross-origin documents.\n COOP will process-isolate your document and potential attackers can't access your global\n object if they were to open it in a popup, preventing a set of cross-origin attacks dubbed XS-Leaks.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Cross-Origin-Resource-Policy": { + "description": "The HTTP Cross-Origin-Resource-Policy response header conveys a desire that the\n browser blocks no-cors cross-origin/cross-site requests to the given resource.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Permissions-Policy": { + "description": "The HTTP Permissions-Policy header provides a mechanism to allow and deny the\n use of browser features in a document or within any \\ elements in the document.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Service-Worker-Allowed": { + "description": "The HTTP Service-Worker-Allowed response header is used to broaden the path restriction for a\n service worker's default scope.\n\n By default, the scope for a service worker registration is the directory where the service\n worker script is located. For example, if the script `sw.js` is located in `/js/sw.js`,\n it can only control URLs under `/js/` by default. Servers can use the `Service-Worker-Allowed`\n header to allow a service worker to control URLs outside of its own directory.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Timing-Allow-Origin": { + "description": "The Timing-Allow-Origin response header specifies origins that are allowed to see values\n of attributes retrieved via features of the Resource Timing API, which would otherwise be\n reported as zero due to cross-origin restrictions.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "X-Content-Type-Options": { + "description": "The X-Content-Type-Options response HTTP header is a marker used by the server to indicate\n that the MIME types advertised in the Content-Type headers should be followed and not be\n changed. The header allows you to avoid MIME type sniffing by saying that the MIME types\n are deliberately configured.\n\n See ", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + }, + "Tauri-Custom-Header": { + "description": "A custom header field Tauri-Custom-Header, don't use it.\n Remember to set Access-Control-Expose-Headers accordingly\n\n **NOT INTENDED FOR PRODUCTION USE**", + "anyOf": [ + { + "$ref": "#/definitions/HeaderSource" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "HeaderSource": { + "description": "definition of a header source\n\n The header value to a header name", + "anyOf": [ + { + "description": "string version of the header Value", + "type": "string" + }, + { + "description": "list version of the header value. Item are joined by \",\" for the real header value", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "(Rust struct | Json | JavaScript Object) equivalent of the header value. Items are composed from: key + space + value. Item are then joined by \";\" for the real header value", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + ] + }, + "TrayIconConfig": { + "description": "Configuration for application tray icon.\n\n See more: ", + "type": "object", + "required": [ + "iconPath" + ], + "properties": { + "id": { + "description": "Set an id for this tray icon so you can reference it later, defaults to `main`.", + "type": [ + "string", + "null" + ] + }, + "iconPath": { + "description": "Path to the default icon to use for the tray icon.\n\n Note: this stores the image in raw pixels to the final binary,\n so keep the icon size (width and height) small\n or else it's going to bloat your final executable", + "type": "string" + }, + "iconAsTemplate": { + "description": "A Boolean value that determines whether the image represents a [template](https://developer.apple.com/documentation/appkit/nsimage/1520017-template?language=objc) image on macOS.", + "default": false, + "type": "boolean" + }, + "menuOnLeftClick": { + "description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.", + "default": true, + "deprecated": true, + "type": "boolean" + }, + "showMenuOnLeftClick": { + "description": "A Boolean value that determines whether the menu should appear when the tray icon receives a left click.\n\n ## Platform-specific:\n\n - **Linux**: Unsupported.", + "default": true, + "type": "boolean" + }, + "title": { + "description": "Title for MacOS tray", + "type": [ + "string", + "null" + ] + }, + "tooltip": { + "description": "Tray icon tooltip on Windows and macOS", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "BuildConfig": { + "description": "The Build configuration object.\n\n See more: ", + "type": "object", + "properties": { + "runner": { + "description": "The binary used to build and run the application.", + "anyOf": [ + { + "$ref": "#/definitions/RunnerConfig" + }, + { + "type": "null" + } + ] + }, + "devUrl": { + "description": "The URL to load in development.\n\n This is usually an URL to a dev server, which serves your application assets with hot-reload and HMR.\n Most modern JavaScript bundlers like [Vite](https://vite.dev/guide/) provides a way to start a dev server by default.\n\n If you don't have a dev server or don't want to use one, ignore this option and use [`frontendDist`](BuildConfig::frontend_dist)\n and point to a web assets directory, and Tauri CLI will run its built-in dev server and provide a simple hot-reload experience.", + "type": [ + "string", + "null" + ], + "format": "uri" + }, + "frontendDist": { + "description": "The path to the application assets (usually the `dist` folder of your javascript bundler)\n or a URL that could be either a custom protocol registered in the tauri app (for example: `myprotocol://`)\n or a remote URL (for example: `https://site.com/app`).\n\n When a path relative to the configuration file is provided,\n it is read recursively and all files are embedded in the application binary.\n Tauri then looks for an `index.html` and serves it as the default entry point for your application.\n\n You can also provide a list of paths to be embedded, which allows granular control over what files are added to the binary.\n In this case, all files are added to the root and you must reference it that way in your HTML files.\n\n When a URL is provided, the application won't have bundled assets\n and the application will load that URL by default.", + "anyOf": [ + { + "$ref": "#/definitions/FrontendDist" + }, + { + "type": "null" + } + ] + }, + "beforeDevCommand": { + "description": "A shell command to run before `tauri dev` kicks in.\n\n The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.", + "anyOf": [ + { + "$ref": "#/definitions/BeforeDevCommand" + }, + { + "type": "null" + } + ] + }, + "beforeBuildCommand": { + "description": "A shell command to run before `tauri build` kicks in.\n\n The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.", + "anyOf": [ + { + "$ref": "#/definitions/HookCommand" + }, + { + "type": "null" + } + ] + }, + "beforeBundleCommand": { + "description": "A shell command to run before the bundling phase in `tauri build` kicks in.\n\n The TAURI_ENV_PLATFORM, TAURI_ENV_ARCH, TAURI_ENV_FAMILY, TAURI_ENV_PLATFORM_VERSION, TAURI_ENV_PLATFORM_TYPE and TAURI_ENV_DEBUG environment variables are set if you perform conditional compilation.", + "anyOf": [ + { + "$ref": "#/definitions/HookCommand" + }, + { + "type": "null" + } + ] + }, + "features": { + "description": "Features passed to `cargo` commands.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "removeUnusedCommands": { + "description": "Try to remove unused commands registered from plugins base on the ACL list during `tauri build`,\n the way it works is that tauri-cli will read this and set the environment variables for the build script and macros,\n and they'll try to get all the allowed commands and remove the rest\n\n Note:\n - This won't be accounting for dynamically added ACLs when you use features from the `dynamic-acl` (currently enabled by default) feature flag, so make sure to check it when using this\n - This feature requires tauri-plugin 2.1 and tauri 2.4", + "default": false, + "type": "boolean" + }, + "additionalWatchFolders": { + "description": "Additional paths to watch for changes when running `tauri dev`.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "RunnerConfig": { + "description": "The runner configuration.", + "anyOf": [ + { + "description": "A string specifying the binary to run.", + "type": "string" + }, + { + "description": "An object with advanced configuration options.", + "type": "object", + "required": [ + "cmd" + ], + "properties": { + "cmd": { + "description": "The binary to run.", + "type": "string" + }, + "cwd": { + "description": "The current working directory to run the command from.", + "type": [ + "string", + "null" + ] + }, + "args": { + "description": "Arguments to pass to the command.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + } + } + ] + }, + "FrontendDist": { + "description": "Defines the URL or assets to embed in the application.", + "anyOf": [ + { + "description": "An external URL that should be used as the default application URL.", + "type": "string", + "format": "uri" + }, + { + "description": "Path to a directory containing the frontend dist assets.", + "type": "string" + }, + { + "description": "An array of files to embed on the app.", + "type": "array", + "items": { + "type": "string" + } + } + ] + }, + "BeforeDevCommand": { + "description": "Describes the shell command to run before `tauri dev`.", + "anyOf": [ + { + "description": "Run the given script with the default options.", + "type": "string" + }, + { + "description": "Run the given script with custom options.", + "type": "object", + "required": [ + "script" + ], + "properties": { + "script": { + "description": "The script to execute.", + "type": "string" + }, + "cwd": { + "description": "The current working directory.", + "type": [ + "string", + "null" + ] + }, + "wait": { + "description": "Whether `tauri dev` should wait for the command to finish or not. Defaults to `false`.", + "default": false, + "type": "boolean" + } + } + } + ] + }, + "HookCommand": { + "description": "Describes a shell command to be executed when a CLI hook is triggered.", + "anyOf": [ + { + "description": "Run the given script with the default options.", + "type": "string" + }, + { + "description": "Run the given script with custom options.", + "type": "object", + "required": [ + "script" + ], + "properties": { + "script": { + "description": "The script to execute.", + "type": "string" + }, + "cwd": { + "description": "The current working directory.", + "type": [ + "string", + "null" + ] + } + } + } + ] + }, + "BundleConfig": { + "description": "Configuration for tauri-bundler.\n\n See more: ", + "type": "object", + "properties": { + "active": { + "description": "Whether Tauri should bundle your application or just output the executable.", + "default": false, + "type": "boolean" + }, + "targets": { + "description": "The bundle targets, currently supports [\"deb\", \"rpm\", \"appimage\", \"nsis\", \"msi\", \"app\", \"dmg\"] or \"all\".", + "default": "all", + "allOf": [ + { + "$ref": "#/definitions/BundleTarget" + } + ] + }, + "createUpdaterArtifacts": { + "description": "Produce updaters and their signatures or not", + "default": false, + "allOf": [ + { + "$ref": "#/definitions/Updater" + } + ] + }, + "publisher": { + "description": "The application's publisher. Defaults to the second element in the identifier string.\n\n Currently maps to the Manufacturer property of the Windows Installer\n and the Maintainer field of debian packages if the Cargo.toml does not have the authors field.", + "type": [ + "string", + "null" + ] + }, + "homepage": { + "description": "A url to the home page of your application. If unset, will\n fallback to `homepage` defined in `Cargo.toml`.\n\n Supported bundle targets: `deb`, `rpm`, `nsis` and `msi`.", + "type": [ + "string", + "null" + ] + }, + "icon": { + "description": "The app's icons", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "resources": { + "description": "App resources to bundle.\n Each resource is a path to a file or directory.\n Glob patterns are supported.\n\n ## Examples\n\n To include a list of files:\n\n ```json\n {\n \"bundle\": {\n \"resources\": [\n \"./path/to/some-file.txt\",\n \"/absolute/path/to/textfile.txt\",\n \"../relative/path/to/jsonfile.json\",\n \"some-folder/\",\n \"resources/**/*.md\"\n ]\n }\n }\n ```\n\n The bundled files will be in `$RESOURCES/` with the original directory structure preserved,\n for example: `./path/to/some-file.txt` -> `$RESOURCE/path/to/some-file.txt`\n\n To fine control where the files will get copied to, use a map instead\n\n ```json\n {\n \"bundle\": {\n \"resources\": {\n \"/absolute/path/to/textfile.txt\": \"resources/textfile.txt\",\n \"relative/path/to/jsonfile.json\": \"resources/jsonfile.json\",\n \"resources/\": \"\",\n \"docs/**/*md\": \"website-docs/\"\n }\n }\n }\n ```\n\n Note that when using glob pattern in this case, the original directory structure is not preserved,\n everything gets copied to the target directory directly\n\n See more: ", + "anyOf": [ + { + "$ref": "#/definitions/BundleResources" + }, + { + "type": "null" + } + ] + }, + "copyright": { + "description": "A copyright string associated with your application.", + "type": [ + "string", + "null" + ] + }, + "license": { + "description": "The package's license identifier to be included in the appropriate bundles.\n If not set, defaults to the license from the Cargo.toml file.", + "type": [ + "string", + "null" + ] + }, + "licenseFile": { + "description": "The path to the license file to be included in the appropriate bundles.", + "type": [ + "string", + "null" + ] + }, + "category": { + "description": "The application kind.\n\n Should be one of the following:\n Business, DeveloperTool, Education, Entertainment, Finance, Game, ActionGame, AdventureGame, ArcadeGame, BoardGame, CardGame, CasinoGame, DiceGame, EducationalGame, FamilyGame, KidsGame, MusicGame, PuzzleGame, RacingGame, RolePlayingGame, SimulationGame, SportsGame, StrategyGame, TriviaGame, WordGame, GraphicsAndDesign, HealthcareAndFitness, Lifestyle, Medical, Music, News, Photography, Productivity, Reference, SocialNetworking, Sports, Travel, Utility, Video, Weather.", + "type": [ + "string", + "null" + ] + }, + "fileAssociations": { + "description": "File types to associate with the application.", + "type": [ + "array", + "null" + ], + "items": { + "$ref": "#/definitions/FileAssociation" + } + }, + "shortDescription": { + "description": "A short description of your application.", + "type": [ + "string", + "null" + ] + }, + "longDescription": { + "description": "A longer, multi-line description of the application.", + "type": [ + "string", + "null" + ] + }, + "useLocalToolsDir": { + "description": "Whether to use the project's `target` directory, for caching build tools (e.g., Wix and NSIS) when building this application. Defaults to `false`.\n\n If true, tools will be cached in `target/.tauri/`.\n If false, tools will be cached in the current user's platform-specific cache directory.\n\n An example where it can be appropriate to set this to `true` is when building this application as a Windows System user (e.g., AWS EC2 workloads),\n because the Window system's app data directory is restricted.", + "default": false, + "type": "boolean" + }, + "externalBin": { + "description": "A list of—either absolute or relative—paths to binaries to embed with your application.\n\n Note that Tauri will look for system-specific binaries following the pattern \"binary-name{-target-triple}{.system-extension}\".\n\n E.g. for the external binary \"my-binary\", Tauri looks for:\n\n - \"my-binary-x86_64-pc-windows-msvc.exe\" for Windows\n - \"my-binary-x86_64-apple-darwin\" for macOS\n - \"my-binary-x86_64-unknown-linux-gnu\" for Linux\n\n so don't forget to provide binaries for all targeted platforms.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "windows": { + "description": "Configuration for the Windows bundles.", + "default": { + "allowDowngrades": true, + "certificateThumbprint": null, + "digestAlgorithm": null, + "nsis": null, + "signCommand": null, + "timestampUrl": null, + "tsp": false, + "webviewInstallMode": { + "silent": true, + "type": "downloadBootstrapper" + }, + "wix": null + }, + "allOf": [ + { + "$ref": "#/definitions/WindowsConfig" + } + ] + }, + "linux": { + "description": "Configuration for the Linux bundles.", + "default": { + "appimage": { + "bundleMediaFramework": false, + "files": {} + }, + "deb": { + "files": {} + }, + "rpm": { + "epoch": 0, + "files": {}, + "release": "1" + } + }, + "allOf": [ + { + "$ref": "#/definitions/LinuxConfig" + } + ] + }, + "macOS": { + "description": "Configuration for the macOS bundles.", + "default": { + "dmg": { + "appPosition": { + "x": 180, + "y": 170 + }, + "applicationFolderPosition": { + "x": 480, + "y": 170 + }, + "windowSize": { + "height": 400, + "width": 660 + } + }, + "files": {}, + "hardenedRuntime": true, + "minimumSystemVersion": "10.13" + }, + "allOf": [ + { + "$ref": "#/definitions/MacConfig" + } + ] + }, + "iOS": { + "description": "iOS configuration.", + "default": { + "minimumSystemVersion": "14.0" + }, + "allOf": [ + { + "$ref": "#/definitions/IosConfig" + } + ] + }, + "android": { + "description": "Android configuration.", + "default": { + "autoIncrementVersionCode": false, + "minSdkVersion": 24 + }, + "allOf": [ + { + "$ref": "#/definitions/AndroidConfig" + } + ] + } + }, + "additionalProperties": false + }, + "BundleTarget": { + "description": "Targets to bundle. Each value is case insensitive.", + "anyOf": [ + { + "description": "Bundle all targets.", + "const": "all" + }, + { + "description": "A list of bundle targets.", + "type": "array", + "items": { + "$ref": "#/definitions/BundleType" + } + }, + { + "description": "A single bundle target.", + "allOf": [ + { + "$ref": "#/definitions/BundleType" + } + ] + } + ] + }, + "BundleType": { + "description": "A bundle referenced by tauri-bundler.", + "oneOf": [ + { + "description": "The debian bundle (.deb).", + "type": "string", + "enum": [ + "deb" + ] + }, + { + "description": "The RPM bundle (.rpm).", + "type": "string", + "enum": [ + "rpm" + ] + }, + { + "description": "The AppImage bundle (.appimage).", + "type": "string", + "enum": [ + "appimage" + ] + }, + { + "description": "The Microsoft Installer bundle (.msi).", + "type": "string", + "enum": [ + "msi" + ] + }, + { + "description": "The NSIS bundle (.exe).", + "type": "string", + "enum": [ + "nsis" + ] + }, + { + "description": "The macOS application bundle (.app).", + "type": "string", + "enum": [ + "app" + ] + }, + { + "description": "The Apple Disk Image bundle (.dmg).", + "type": "string", + "enum": [ + "dmg" + ] + } + ] + }, + "Updater": { + "description": "Updater type", + "anyOf": [ + { + "description": "Generates legacy zipped v1 compatible updaters", + "allOf": [ + { + "$ref": "#/definitions/V1Compatible" + } + ] + }, + { + "description": "Produce updaters and their signatures or not", + "type": "boolean" + } + ] + }, + "V1Compatible": { + "description": "Generates legacy zipped v1 compatible updaters", + "oneOf": [ + { + "description": "Generates legacy zipped v1 compatible updaters", + "type": "string", + "enum": [ + "v1Compatible" + ] + } + ] + }, + "BundleResources": { + "description": "Definition for bundle resources.\n Can be either a list of paths to include or a map of source to target paths.", + "anyOf": [ + { + "description": "A list of paths to include.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "A map of source to target paths.", + "type": "object", + "additionalProperties": { + "type": "string" + } + } + ] + }, + "FileAssociation": { + "description": "File association", + "type": "object", + "required": [ + "ext" + ], + "properties": { + "ext": { + "description": "File extensions to associate with this app. e.g. 'png'", + "type": "array", + "items": { + "$ref": "#/definitions/AssociationExt" + } + }, + "contentTypes": { + "description": "Declare support to a file with the given content type. Maps to `LSItemContentTypes` on macOS.\n\n This allows supporting any file format declared by another application that conforms to this type.\n Declaration of new types can be done with [`Self::exported_type`] and linking to certain content types are done via [`ExportedFileAssociation::conforms_to`].", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "name": { + "description": "The name. Maps to `CFBundleTypeName` on macOS. Default to `ext[0]`", + "type": [ + "string", + "null" + ] + }, + "description": { + "description": "The association description. Windows-only. It is displayed on the `Type` column on Windows Explorer.", + "type": [ + "string", + "null" + ] + }, + "role": { + "description": "The app's role with respect to the type. Maps to `CFBundleTypeRole` on macOS.", + "default": "Editor", + "allOf": [ + { + "$ref": "#/definitions/BundleTypeRole" + } + ] + }, + "mimeType": { + "description": "The mime-type e.g. 'image/png' or 'text/plain'. Linux-only.", + "type": [ + "string", + "null" + ] + }, + "rank": { + "description": "The ranking of this app among apps that declare themselves as editors or viewers of the given file type. Maps to `LSHandlerRank` on macOS.", + "default": "Default", + "allOf": [ + { + "$ref": "#/definitions/HandlerRank" + } + ] + }, + "exportedType": { + "description": "The exported type definition. Maps to a `UTExportedTypeDeclarations` entry on macOS.\n\n You should define this if the associated file is a custom file type defined by your application.", + "anyOf": [ + { + "$ref": "#/definitions/ExportedFileAssociation" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "AssociationExt": { + "description": "An extension for a [`FileAssociation`].\n\n A leading `.` is automatically stripped.", + "type": "string" + }, + "BundleTypeRole": { + "description": "macOS-only. Corresponds to CFBundleTypeRole", + "oneOf": [ + { + "description": "CFBundleTypeRole.Editor. Files can be read and edited.", + "type": "string", + "enum": [ + "Editor" + ] + }, + { + "description": "CFBundleTypeRole.Viewer. Files can be read.", + "type": "string", + "enum": [ + "Viewer" + ] + }, + { + "description": "CFBundleTypeRole.Shell", + "type": "string", + "enum": [ + "Shell" + ] + }, + { + "description": "CFBundleTypeRole.QLGenerator", + "type": "string", + "enum": [ + "QLGenerator" + ] + }, + { + "description": "CFBundleTypeRole.None", + "type": "string", + "enum": [ + "None" + ] + } + ] + }, + "HandlerRank": { + "description": "Corresponds to LSHandlerRank", + "oneOf": [ + { + "description": "LSHandlerRank.Default. This app is an opener of files of this type; this value is also used if no rank is specified.", + "type": "string", + "enum": [ + "Default" + ] + }, + { + "description": "LSHandlerRank.Owner. This app is the primary creator of files of this type.", + "type": "string", + "enum": [ + "Owner" + ] + }, + { + "description": "LSHandlerRank.Alternate. This app is a secondary viewer of files of this type.", + "type": "string", + "enum": [ + "Alternate" + ] + }, + { + "description": "LSHandlerRank.None. This app is never selected to open files of this type, but it accepts drops of files of this type.", + "type": "string", + "enum": [ + "None" + ] + } + ] + }, + "ExportedFileAssociation": { + "description": "The exported type definition. Maps to a `UTExportedTypeDeclarations` entry on macOS.", + "type": "object", + "required": [ + "identifier" + ], + "properties": { + "identifier": { + "description": "The unique identifier for the exported type. Maps to `UTTypeIdentifier`.", + "type": "string" + }, + "conformsTo": { + "description": "The types that this type conforms to. Maps to `UTTypeConformsTo`.\n\n Examples are `public.data`, `public.image`, `public.json` and `public.database`.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "WindowsConfig": { + "description": "Windows bundler configuration.\n\n See more: ", + "type": "object", + "properties": { + "digestAlgorithm": { + "description": "Specifies the file digest algorithm to use for creating file signatures.\n Required for code signing. SHA-256 is recommended.", + "type": [ + "string", + "null" + ] + }, + "certificateThumbprint": { + "description": "Specifies the SHA1 hash of the signing certificate.", + "type": [ + "string", + "null" + ] + }, + "timestampUrl": { + "description": "Server to use during timestamping.", + "type": [ + "string", + "null" + ] + }, + "tsp": { + "description": "Whether to use Time-Stamp Protocol (TSP, a.k.a. RFC 3161) for the timestamp server. Your code signing provider may\n use a TSP timestamp server, like e.g. SSL.com does. If so, enable TSP by setting to true.", + "default": false, + "type": "boolean" + }, + "webviewInstallMode": { + "description": "The installation mode for the Webview2 runtime.", + "default": { + "silent": true, + "type": "downloadBootstrapper" + }, + "allOf": [ + { + "$ref": "#/definitions/WebviewInstallMode" + } + ] + }, + "allowDowngrades": { + "description": "Validates a second app installation, blocking the user from installing an older version if set to `false`.\n\n For instance, if `1.2.1` is installed, the user won't be able to install app version `1.2.0` or `1.1.5`.\n\n The default value of this flag is `true`.", + "default": true, + "type": "boolean" + }, + "wix": { + "description": "Configuration for the MSI generated with WiX.", + "anyOf": [ + { + "$ref": "#/definitions/WixConfig" + }, + { + "type": "null" + } + ] + }, + "nsis": { + "description": "Configuration for the installer generated with NSIS.", + "anyOf": [ + { + "$ref": "#/definitions/NsisConfig" + }, + { + "type": "null" + } + ] + }, + "signCommand": { + "description": "Specify a custom command to sign the binaries.\n This command needs to have a `%1` in args which is just a placeholder for the binary path,\n which we will detect and replace before calling the command.\n\n By Default we use `signtool.exe` which can be found only on Windows so\n if you are on another platform and want to cross-compile and sign you will\n need to use another tool like `osslsigncode`.", + "anyOf": [ + { + "$ref": "#/definitions/CustomSignCommandConfig" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "WebviewInstallMode": { + "description": "Install modes for the Webview2 runtime.\n Note that for the updater bundle [`Self::DownloadBootstrapper`] is used.\n\n For more information see .", + "oneOf": [ + { + "description": "Do not install the Webview2 as part of the Windows Installer.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "skip" + ] + } + }, + "additionalProperties": false + }, + { + "description": "Download the bootstrapper and run it.\n Requires an internet connection.\n Results in a smaller installer size, but is not recommended on Windows 7.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "downloadBootstrapper" + ] + }, + "silent": { + "description": "Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.", + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "description": "Embed the bootstrapper and run it.\n Requires an internet connection.\n Increases the installer size by around 1.8MB, but offers better support on Windows 7.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "embedBootstrapper" + ] + }, + "silent": { + "description": "Instructs the installer to run the bootstrapper in silent mode. Defaults to `true`.", + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "description": "Embed the offline installer and run it.\n Does not require an internet connection.\n Increases the installer size by around 127MB.", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "offlineInstaller" + ] + }, + "silent": { + "description": "Instructs the installer to run the installer in silent mode. Defaults to `true`.", + "default": true, + "type": "boolean" + } + }, + "additionalProperties": false + }, + { + "description": "Embed a fixed webview2 version and use it at runtime.\n Increases the installer size by around 180MB.", + "type": "object", + "required": [ + "path", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "fixedRuntime" + ] + }, + "path": { + "description": "The path to the fixed runtime to use.\n\n The fixed version can be downloaded [on the official website](https://developer.microsoft.com/en-us/microsoft-edge/webview2/#download-section).\n The `.cab` file must be extracted to a folder and this folder path must be defined on this field.", + "type": "string" + } + }, + "additionalProperties": false + } + ] + }, + "WixConfig": { + "description": "Configuration for the MSI bundle using WiX.\n\n See more: ", + "type": "object", + "properties": { + "version": { + "description": "MSI installer version in the format `major.minor.patch.build` (build is optional).\n\n Because a valid version is required for MSI installer, it will be derived from [`Config::version`] if this field is not set.\n\n The first field is the major version and has a maximum value of 255. The second field is the minor version and has a maximum value of 255.\n The third and foruth fields have a maximum value of 65,535.\n\n See for more info.", + "type": [ + "string", + "null" + ] + }, + "upgradeCode": { + "description": "A GUID upgrade code for MSI installer. This code **_must stay the same across all of your updates_**,\n otherwise, Windows will treat your update as a different app and your users will have duplicate versions of your app.\n\n By default, tauri generates this code by generating a Uuid v5 using the string `.exe.app.x64` in the DNS namespace.\n You can use Tauri's CLI to generate and print this code for you, run `tauri inspect wix-upgrade-code`.\n\n It is recommended that you set this value in your tauri config file to avoid accidental changes in your upgrade code\n whenever you want to change your product name.", + "type": [ + "string", + "null" + ], + "format": "uuid" + }, + "language": { + "description": "The installer languages to build. See .", + "default": "en-US", + "allOf": [ + { + "$ref": "#/definitions/WixLanguage" + } + ] + }, + "template": { + "description": "A custom .wxs template to use.", + "type": [ + "string", + "null" + ] + }, + "fragmentPaths": { + "description": "A list of paths to .wxs files with WiX fragments to use.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "componentGroupRefs": { + "description": "The ComponentGroup element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "componentRefs": { + "description": "The Component element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "featureGroupRefs": { + "description": "The FeatureGroup element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "featureRefs": { + "description": "The Feature element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "mergeRefs": { + "description": "The Merge element ids you want to reference from the fragments.", + "default": [], + "type": "array", + "items": { + "type": "string" + } + }, + "enableElevatedUpdateTask": { + "description": "Create an elevated update task within Windows Task Scheduler.", + "default": false, + "type": "boolean" + }, + "bannerPath": { + "description": "Path to a bitmap file to use as the installation user interface banner.\n This bitmap will appear at the top of all but the first page of the installer.\n\n The required dimensions are 493px × 58px.", + "type": [ + "string", + "null" + ] + }, + "dialogImagePath": { + "description": "Path to a bitmap file to use on the installation user interface dialogs.\n It is used on the welcome and completion dialogs.\n\n The required dimensions are 493px × 312px.", + "type": [ + "string", + "null" + ] + }, + "fipsCompliant": { + "description": "Enables FIPS compliant algorithms.\n Can also be enabled via the `TAURI_BUNDLER_WIX_FIPS_COMPLIANT` env var.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "WixLanguage": { + "description": "The languages to build using WiX.", + "anyOf": [ + { + "description": "A single language to build, without configuration.", + "type": "string" + }, + { + "description": "A list of languages to build, without configuration.", + "type": "array", + "items": { + "type": "string" + } + }, + { + "description": "A map of languages and its configuration.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/WixLanguageConfig" + } + } + ] + }, + "WixLanguageConfig": { + "description": "Configuration for a target language for the WiX build.\n\n See more: ", + "type": "object", + "properties": { + "localePath": { + "description": "The path to a locale (`.wxl`) file. See .", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "NsisConfig": { + "description": "Configuration for the Installer bundle using NSIS.", + "type": "object", + "properties": { + "template": { + "description": "A custom .nsi template to use.", + "type": [ + "string", + "null" + ] + }, + "headerImage": { + "description": "The path to a bitmap file to display on the header of installers pages.\n\n The recommended dimensions are 150px x 57px.", + "type": [ + "string", + "null" + ] + }, + "sidebarImage": { + "description": "The path to a bitmap file for the Welcome page and the Finish page.\n\n The recommended dimensions are 164px x 314px.", + "type": [ + "string", + "null" + ] + }, + "installerIcon": { + "description": "The path to an icon file used as the installer icon.", + "type": [ + "string", + "null" + ] + }, + "installMode": { + "description": "Whether the installation will be for all users or just the current user.", + "default": "currentUser", + "allOf": [ + { + "$ref": "#/definitions/NSISInstallerMode" + } + ] + }, + "languages": { + "description": "A list of installer languages.\n By default the OS language is used. If the OS language is not in the list of languages, the first language will be used.\n To allow the user to select the language, set `display_language_selector` to `true`.\n\n See for the complete list of languages.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "customLanguageFiles": { + "description": "A key-value pair where the key is the language and the\n value is the path to a custom `.nsh` file that holds the translated text for tauri's custom messages.\n\n See for an example `.nsh` file.\n\n **Note**: the key must be a valid NSIS language and it must be added to [`NsisConfig`] languages array,", + "type": [ + "object", + "null" + ], + "additionalProperties": { + "type": "string" + } + }, + "displayLanguageSelector": { + "description": "Whether to display a language selector dialog before the installer and uninstaller windows are rendered or not.\n By default the OS language is selected, with a fallback to the first language in the `languages` array.", + "default": false, + "type": "boolean" + }, + "compression": { + "description": "Set the compression algorithm used to compress files in the installer.\n\n See ", + "default": "lzma", + "allOf": [ + { + "$ref": "#/definitions/NsisCompression" + } + ] + }, + "startMenuFolder": { + "description": "Set the folder name for the start menu shortcut.\n\n Use this option if you have multiple apps and wish to group their shortcuts under one folder\n or if you generally prefer to set your shortcut inside a folder.\n\n Examples:\n - `AwesomePublisher`, shortcut will be placed in `%AppData%\\Microsoft\\Windows\\Start Menu\\Programs\\AwesomePublisher\\.lnk`\n - If unset, shortcut will be placed in `%AppData%\\Microsoft\\Windows\\Start Menu\\Programs\\.lnk`", + "type": [ + "string", + "null" + ] + }, + "installerHooks": { + "description": "A path to a `.nsh` file that contains special NSIS macros to be hooked into the\n main installer.nsi script.\n\n Supported hooks are:\n\n - `NSIS_HOOK_PREINSTALL`: This hook runs before copying files, setting registry key values and creating shortcuts.\n - `NSIS_HOOK_POSTINSTALL`: This hook runs after the installer has finished copying all files, setting the registry keys and created shortcuts.\n - `NSIS_HOOK_PREUNINSTALL`: This hook runs before removing any files, registry keys and shortcuts.\n - `NSIS_HOOK_POSTUNINSTALL`: This hook runs after files, registry keys and shortcuts have been removed.\n\n ### Example\n\n ```nsh\n !macro NSIS_HOOK_PREINSTALL\n MessageBox MB_OK \"PreInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTINSTALL\n MessageBox MB_OK \"PostInstall\"\n !macroend\n\n !macro NSIS_HOOK_PREUNINSTALL\n MessageBox MB_OK \"PreUnInstall\"\n !macroend\n\n !macro NSIS_HOOK_POSTUNINSTALL\n MessageBox MB_OK \"PostUninstall\"\n !macroend\n ```", + "type": [ + "string", + "null" + ] + }, + "minimumWebview2Version": { + "description": "Try to ensure that the WebView2 version is equal to or newer than this version,\n if the user's WebView2 is older than this version,\n the installer will try to trigger a WebView2 update.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "NSISInstallerMode": { + "description": "Install Modes for the NSIS installer.", + "oneOf": [ + { + "description": "Default mode for the installer.\n\n Install the app by default in a directory that doesn't require Administrator access.\n\n Installer metadata will be saved under the `HKCU` registry path.", + "type": "string", + "enum": [ + "currentUser" + ] + }, + { + "description": "Install the app by default in the `Program Files` folder directory requires Administrator\n access for the installation.\n\n Installer metadata will be saved under the `HKLM` registry path.", + "type": "string", + "enum": [ + "perMachine" + ] + }, + { + "description": "Combines both modes and allows the user to choose at install time\n whether to install for the current user or per machine. Note that this mode\n will require Administrator access even if the user wants to install it for the current user only.\n\n Installer metadata will be saved under the `HKLM` or `HKCU` registry path based on the user's choice.", + "type": "string", + "enum": [ + "both" + ] + } + ] + }, + "NsisCompression": { + "description": "Compression algorithms used in the NSIS installer.\n\n See ", + "oneOf": [ + { + "description": "ZLIB uses the deflate algorithm, it is a quick and simple method. With the default compression level it uses about 300 KB of memory.", + "type": "string", + "enum": [ + "zlib" + ] + }, + { + "description": "BZIP2 usually gives better compression ratios than ZLIB, but it is a bit slower and uses more memory. With the default compression level it uses about 4 MB of memory.", + "type": "string", + "enum": [ + "bzip2" + ] + }, + { + "description": "LZMA (default) is a new compression method that gives very good compression ratios. The decompression speed is high (10-20 MB/s on a 2 GHz CPU), the compression speed is lower. The memory size that will be used for decompression is the dictionary size plus a few KBs, the default is 8 MB.", + "type": "string", + "enum": [ + "lzma" + ] + }, + { + "description": "Disable compression", + "type": "string", + "enum": [ + "none" + ] + } + ] + }, + "CustomSignCommandConfig": { + "description": "Custom Signing Command configuration.", + "anyOf": [ + { + "description": "A string notation of the script to execute.\n\n \"%1\" will be replaced with the path to the binary to be signed.\n\n This is a simpler notation for the command.\n Tauri will split the string with `' '` and use the first element as the command name and the rest as arguments.\n\n If you need to use whitespace in the command or arguments, use the object notation [`Self::ScriptWithOptions`].", + "type": "string" + }, + { + "description": "An object notation of the command.\n\n This is more complex notation for the command but\n this allows you to use whitespace in the command and arguments.", + "type": "object", + "required": [ + "args", + "cmd" + ], + "properties": { + "cmd": { + "description": "The command to run to sign the binary.", + "type": "string" + }, + "args": { + "description": "The arguments to pass to the command.\n\n \"%1\" will be replaced with the path to the binary to be signed.", + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + } + ] + }, + "LinuxConfig": { + "description": "Configuration for Linux bundles.\n\n See more: ", + "type": "object", + "properties": { + "appimage": { + "description": "Configuration for the AppImage bundle.", + "default": { + "bundleMediaFramework": false, + "files": {} + }, + "allOf": [ + { + "$ref": "#/definitions/AppImageConfig" + } + ] + }, + "deb": { + "description": "Configuration for the Debian bundle.", + "default": { + "files": {} + }, + "allOf": [ + { + "$ref": "#/definitions/DebConfig" + } + ] + }, + "rpm": { + "description": "Configuration for the RPM bundle.", + "default": { + "epoch": 0, + "files": {}, + "release": "1" + }, + "allOf": [ + { + "$ref": "#/definitions/RpmConfig" + } + ] + } + }, + "additionalProperties": false + }, + "AppImageConfig": { + "description": "Configuration for AppImage bundles.\n\n See more: ", + "type": "object", + "properties": { + "bundleMediaFramework": { + "description": "Include additional gstreamer dependencies needed for audio and video playback.\n This increases the bundle size by ~15-35MB depending on your build system.", + "default": false, + "type": "boolean" + }, + "files": { + "description": "The files to include in the Appimage Binary.", + "default": {}, + "type": "object", + "additionalProperties": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "DebConfig": { + "description": "Configuration for Debian (.deb) bundles.\n\n See more: ", + "type": "object", + "properties": { + "depends": { + "description": "The list of deb dependencies your application relies on.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "recommends": { + "description": "The list of deb dependencies your application recommends.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "provides": { + "description": "The list of dependencies the package provides.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "conflicts": { + "description": "The list of package conflicts.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "replaces": { + "description": "The list of package replaces.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "files": { + "description": "The files to include on the package.", + "default": {}, + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "section": { + "description": "Define the section in Debian Control file. See : https://www.debian.org/doc/debian-policy/ch-archive.html#s-subsections", + "type": [ + "string", + "null" + ] + }, + "priority": { + "description": "Change the priority of the Debian Package. By default, it is set to `optional`.\n Recognized Priorities as of now are : `required`, `important`, `standard`, `optional`, `extra`", + "type": [ + "string", + "null" + ] + }, + "changelog": { + "description": "Path of the uncompressed Changelog file, to be stored at /usr/share/doc/package-name/changelog.gz. See\n ", + "type": [ + "string", + "null" + ] + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\n Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See\n ", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See\n ", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See\n ", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See\n ", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "RpmConfig": { + "description": "Configuration for RPM bundles.", + "type": "object", + "properties": { + "depends": { + "description": "The list of RPM dependencies your application relies on.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "recommends": { + "description": "The list of RPM dependencies your application recommends.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "provides": { + "description": "The list of RPM dependencies your application provides.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "conflicts": { + "description": "The list of RPM dependencies your application conflicts with. They must not be present\n in order for the package to be installed.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "obsoletes": { + "description": "The list of RPM dependencies your application supersedes - if this package is installed,\n packages listed as \"obsoletes\" will be automatically removed (if they are present).", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "release": { + "description": "The RPM release tag.", + "default": "1", + "type": "string" + }, + "epoch": { + "description": "The RPM epoch.", + "default": 0, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "files": { + "description": "The files to include on the package.", + "default": {}, + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "desktopTemplate": { + "description": "Path to a custom desktop file Handlebars template.\n\n Available variables: `categories`, `comment` (optional), `exec`, `icon` and `name`.", + "type": [ + "string", + "null" + ] + }, + "preInstallScript": { + "description": "Path to script that will be executed before the package is unpacked. See\n ", + "type": [ + "string", + "null" + ] + }, + "postInstallScript": { + "description": "Path to script that will be executed after the package is unpacked. See\n ", + "type": [ + "string", + "null" + ] + }, + "preRemoveScript": { + "description": "Path to script that will be executed before the package is removed. See\n ", + "type": [ + "string", + "null" + ] + }, + "postRemoveScript": { + "description": "Path to script that will be executed after the package is removed. See\n ", + "type": [ + "string", + "null" + ] + }, + "compression": { + "description": "Compression algorithm and level. Defaults to `Gzip` with level 6.", + "anyOf": [ + { + "$ref": "#/definitions/RpmCompression" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false + }, + "RpmCompression": { + "description": "Compression algorithms used when bundling RPM packages.", + "oneOf": [ + { + "description": "Gzip compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "gzip" + ] + }, + "level": { + "description": "Gzip compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Zstd compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "zstd" + ] + }, + "level": { + "description": "Zstd compression level", + "type": "integer", + "format": "int32" + } + }, + "additionalProperties": false + }, + { + "description": "Xz compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "xz" + ] + }, + "level": { + "description": "Xz compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Bzip2 compression", + "type": "object", + "required": [ + "level", + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "bzip2" + ] + }, + "level": { + "description": "Bzip2 compression level", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + { + "description": "Disable compression", + "type": "object", + "required": [ + "type" + ], + "properties": { + "type": { + "type": "string", + "enum": [ + "none" + ] + } + }, + "additionalProperties": false + } + ] + }, + "MacConfig": { + "description": "Configuration for the macOS bundles.\n\n See more: ", + "type": "object", + "properties": { + "frameworks": { + "description": "A list of strings indicating any macOS X frameworks that need to be bundled with the application.\n\n If a name is used, \".framework\" must be omitted and it will look for standard install locations. You may also use a path to a specific framework.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "files": { + "description": "The files to include in the application relative to the Contents directory.", + "default": {}, + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "bundleVersion": { + "description": "The version of the build that identifies an iteration of the bundle.\n\n Translates to the bundle's CFBundleVersion property.", + "type": [ + "string", + "null" + ] + }, + "bundleName": { + "description": "The name of the builder that built the bundle.\n\n Translates to the bundle's CFBundleName property.\n\n If not set, defaults to the package's product name.", + "type": [ + "string", + "null" + ] + }, + "minimumSystemVersion": { + "description": "A version string indicating the minimum macOS X version that the bundled application supports. Defaults to `10.13`.\n\n Setting it to `null` completely removes the `LSMinimumSystemVersion` field on the bundle's `Info.plist`\n and the `MACOSX_DEPLOYMENT_TARGET` environment variable.\n\n Ignored in `tauri dev`.\n\n An empty string is considered an invalid value so the default value is used.", + "default": "10.13", + "type": [ + "string", + "null" + ] + }, + "exceptionDomain": { + "description": "Allows your application to communicate with the outside world.\n It should be a lowercase, without port and protocol domain name.", + "type": [ + "string", + "null" + ] + }, + "signingIdentity": { + "description": "Identity to use for code signing.", + "type": [ + "string", + "null" + ] + }, + "hardenedRuntime": { + "description": "Whether the codesign should enable [hardened runtime](https://developer.apple.com/documentation/security/hardened_runtime) (for executables) or not.", + "default": true, + "type": "boolean" + }, + "providerShortName": { + "description": "Provider short name for notarization.", + "type": [ + "string", + "null" + ] + }, + "entitlements": { + "description": "Path to the entitlements file.", + "type": [ + "string", + "null" + ] + }, + "infoPlist": { + "description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` file in the same directory as the Tauri configuration file.", + "type": [ + "string", + "null" + ] + }, + "dmg": { + "description": "DMG-specific settings.", + "default": { + "appPosition": { + "x": 180, + "y": 170 + }, + "applicationFolderPosition": { + "x": 480, + "y": 170 + }, + "windowSize": { + "height": 400, + "width": 660 + } + }, + "allOf": [ + { + "$ref": "#/definitions/DmgConfig" + } + ] + } + }, + "additionalProperties": false + }, + "DmgConfig": { + "description": "Configuration for Apple Disk Image (.dmg) bundles.\n\n See more: ", + "type": "object", + "properties": { + "background": { + "description": "Image to use as the background in dmg file. Accepted formats: `png`/`jpg`/`gif`.", + "type": [ + "string", + "null" + ] + }, + "windowPosition": { + "description": "Position of volume window on screen.", + "anyOf": [ + { + "$ref": "#/definitions/Position" + }, + { + "type": "null" + } + ] + }, + "windowSize": { + "description": "Size of volume window.", + "default": { + "height": 400, + "width": 660 + }, + "allOf": [ + { + "$ref": "#/definitions/Size" + } + ] + }, + "appPosition": { + "description": "Position of app file on window.", + "default": { + "x": 180, + "y": 170 + }, + "allOf": [ + { + "$ref": "#/definitions/Position" + } + ] + }, + "applicationFolderPosition": { + "description": "Position of application folder on window.", + "default": { + "x": 480, + "y": 170 + }, + "allOf": [ + { + "$ref": "#/definitions/Position" + } + ] + } + }, + "additionalProperties": false + }, + "Position": { + "description": "Position coordinates struct.", + "type": "object", + "required": [ + "x", + "y" + ], + "properties": { + "x": { + "description": "X coordinate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "y": { + "description": "Y coordinate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Size": { + "description": "Size of the window.", + "type": "object", + "required": [ + "height", + "width" + ], + "properties": { + "width": { + "description": "Width of the window.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "height": { + "description": "Height of the window.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "IosConfig": { + "description": "General configuration for the iOS target.", + "type": "object", + "properties": { + "template": { + "description": "A custom [XcodeGen] project.yml template to use.\n\n [XcodeGen]: ", + "type": [ + "string", + "null" + ] + }, + "frameworks": { + "description": "A list of strings indicating any iOS frameworks that need to be bundled with the application.\n\n Note that you need to recreate the iOS project for the changes to be applied.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, + "developmentTeam": { + "description": "The development team. This value is required for iOS development because code signing is enforced.\n The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.", + "type": [ + "string", + "null" + ] + }, + "bundleVersion": { + "description": "The version of the build that identifies an iteration of the bundle.\n\n Translates to the bundle's CFBundleVersion property.", + "type": [ + "string", + "null" + ] + }, + "minimumSystemVersion": { + "description": "A version string indicating the minimum iOS version that the bundled application supports. Defaults to `13.0`.\n\n Maps to the IPHONEOS_DEPLOYMENT_TARGET value.", + "default": "14.0", + "type": "string" + }, + "infoPlist": { + "description": "Path to a Info.plist file to merge with the default Info.plist.\n\n Note that Tauri also looks for a `Info.plist` and `Info.ios.plist` file in the same directory as the Tauri configuration file.", + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "AndroidConfig": { + "description": "General configuration for the Android target.", + "type": "object", + "properties": { + "minSdkVersion": { + "description": "The minimum API level required for the application to run.\n The Android system will prevent the user from installing the application if the system's API level is lower than the value specified.", + "default": 24, + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "versionCode": { + "description": "The version code of the application.\n It is limited to 2,100,000,000 as per Google Play Store requirements.\n\n By default we use your configured version and perform the following math:\n versionCode = version.major * 1000000 + version.minor * 1000 + version.patch", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "maximum": 2100000000.0, + "minimum": 1.0 + }, + "autoIncrementVersionCode": { + "description": "Whether to automatically increment the `versionCode` on each build.\n\n - If `true`, the generator will try to read the last `versionCode` from\n `tauri.properties` and increment it by 1 for every build.\n - If `false` or not set, it falls back to `version_code` or semver-derived logic.\n\n Note that to use this feature, you should remove `/tauri.properties` from `src-tauri/gen/android/app/.gitignore` so the current versionCode is committed to the repository.", + "default": false, + "type": "boolean" + } + }, + "additionalProperties": false + }, + "PluginConfig": { + "description": "The plugin configs holds a HashMap mapping a plugin name to its configuration object.\n\n See more: ", + "type": "object", + "additionalProperties": true + } + } +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/index.d.ts b/tools/join-backups/node_modules/@tauri-apps/cli/index.d.ts new file mode 100644 index 0000000..956ddc1 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/index.d.ts @@ -0,0 +1,9 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/* auto-generated by NAPI-RS */ +/* eslint-disable */ +export declare function logError(error: string): void + +export declare function run(args: Array, binName: string | undefined | null, callback: ((err: Error | null, arg: boolean) => any)): void diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/index.js b/tools/join-backups/node_modules/@tauri-apps/cli/index.js new file mode 100644 index 0000000..ab5cfc8 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/index.js @@ -0,0 +1,401 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +// prettier-ignore +/* eslint-disable */ +// @ts-nocheck +/* auto-generated by NAPI-RS */ + +const { createRequire } = require('node:module') +require = createRequire(__filename) + +const { readFileSync } = require('node:fs') +let nativeBinding = null +const loadErrors = [] + +const isMusl = () => { + let musl = false + if (process.platform === 'linux') { + musl = isMuslFromFilesystem() + if (musl === null) { + musl = isMuslFromReport() + } + if (musl === null) { + musl = isMuslFromChildProcess() + } + } + return musl +} + +const isFileMusl = (f) => f.includes('libc.musl-') || f.includes('ld-musl-') + +const isMuslFromFilesystem = () => { + try { + return readFileSync('/usr/bin/ldd', 'utf-8').includes('musl') + } catch { + return null + } +} + +const isMuslFromReport = () => { + let report = null + if (typeof process.report?.getReport === 'function') { + process.report.excludeNetwork = true + report = process.report.getReport() + } + if (!report) { + return null + } + if (report.header && report.header.glibcVersionRuntime) { + return false + } + if (Array.isArray(report.sharedObjects)) { + if (report.sharedObjects.some(isFileMusl)) { + return true + } + } + return false +} + +const isMuslFromChildProcess = () => { + try { + return require('child_process').execSync('ldd --version', { encoding: 'utf8' }).includes('musl') + } catch (e) { + // If we reach this case, we don't know if the system is musl or not, so is better to just fallback to false + return false + } +} + +function requireNative() { + if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) { + try { + nativeBinding = require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH); + } catch (err) { + loadErrors.push(err) + } + } else if (process.platform === 'android') { + if (process.arch === 'arm64') { + try { + return require('./cli.android-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-android-arm64') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./cli.android-arm-eabi.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-android-arm-eabi') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`)) + } + } else if (process.platform === 'win32') { + if (process.arch === 'x64') { + try { + return require('./cli.win32-x64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-win32-x64-msvc') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'ia32') { + try { + return require('./cli.win32-ia32-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-win32-ia32-msvc') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./cli.win32-arm64-msvc.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-win32-arm64-msvc') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`)) + } + } else if (process.platform === 'darwin') { + try { + return require('./cli.darwin-universal.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-darwin-universal') + } catch (e) { + loadErrors.push(e) + } + if (process.arch === 'x64') { + try { + return require('./cli.darwin-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-darwin-x64') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./cli.darwin-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-darwin-arm64') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`)) + } + } else if (process.platform === 'freebsd') { + if (process.arch === 'x64') { + try { + return require('./cli.freebsd-x64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-freebsd-x64') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm64') { + try { + return require('./cli.freebsd-arm64.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-freebsd-arm64') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`)) + } + } else if (process.platform === 'linux') { + if (process.arch === 'x64') { + if (isMusl()) { + try { + return require('./cli.linux-x64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-x64-musl') + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./cli.linux-x64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-x64-gnu') + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm64') { + if (isMusl()) { + try { + return require('./cli.linux-arm64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm64-musl') + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./cli.linux-arm64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm64-gnu') + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'arm') { + if (isMusl()) { + try { + return require('./cli.linux-arm-musleabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm-musleabihf') + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./cli.linux-arm-gnueabihf.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm-gnueabihf') + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'riscv64') { + if (isMusl()) { + try { + return require('./cli.linux-riscv64-musl.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-riscv64-musl') + } catch (e) { + loadErrors.push(e) + } + } else { + try { + return require('./cli.linux-riscv64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-riscv64-gnu') + } catch (e) { + loadErrors.push(e) + } + } + } else if (process.arch === 'ppc64') { + try { + return require('./cli.linux-ppc64-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-ppc64-gnu') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 's390x') { + try { + return require('./cli.linux-s390x-gnu.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-s390x-gnu') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`)) + } + } else if (process.platform === 'openharmony') { + if (process.arch === 'arm64') { + try { + return require('./cli.linux-arm64-ohos.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm64-ohos') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'x64') { + try { + return require('./cli.linux-x64-ohos.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-x64-ohos') + } catch (e) { + loadErrors.push(e) + } + } else if (process.arch === 'arm') { + try { + return require('./cli.linux-arm-ohos.node') + } catch (e) { + loadErrors.push(e) + } + try { + return require('@tauri-apps/cli-linux-arm-ohos') + } catch (e) { + loadErrors.push(e) + } + } else { + loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`)) + } + } else { + loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`)) + } +} + +nativeBinding = requireNative() + +if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) { + try { + nativeBinding = require('./cli.wasi.cjs') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadErrors.push(err) + } + } + if (!nativeBinding) { + try { + nativeBinding = require('@tauri-apps/cli-wasm32-wasi') + } catch (err) { + if (process.env.NAPI_RS_FORCE_WASI) { + loadErrors.push(err) + } + } + } +} + +if (!nativeBinding) { + if (loadErrors.length > 0) { + throw new Error( + `Cannot find native binding. ` + + `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + + 'Please try `npm i` again after removing both package-lock.json and node_modules directory.', + { cause: loadErrors } + ) + } + throw new Error(`Failed to load native binding`) +} + +module.exports = nativeBinding +module.exports.logError = nativeBinding.logError +module.exports.run = nativeBinding.run diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/main.d.ts b/tools/join-backups/node_modules/@tauri-apps/cli/main.d.ts new file mode 100644 index 0000000..ee5d858 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/main.d.ts @@ -0,0 +1,11 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +/* tslint:disable */ +/* eslint-disable */ + +export function run( + args: Array, + binName?: string | undefined | null +): Promise diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/main.js b/tools/join-backups/node_modules/@tauri-apps/cli/main.js new file mode 100644 index 0000000..5fb1933 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/main.js @@ -0,0 +1,19 @@ +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +const { run, logError } = require('./index') + +module.exports.run = (args, binName) => { + return new Promise((resolve, reject) => { + run(args, binName, (error, res) => { + if (error) { + reject(error) + } else { + resolve(res) + } + }) + }) +} + +module.exports.logError = logError diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/package.json b/tools/join-backups/node_modules/@tauri-apps/cli/package.json new file mode 100644 index 0000000..91ad208 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/package.json @@ -0,0 +1,80 @@ +{ + "name": "@tauri-apps/cli", + "version": "2.9.6", + "description": "Command line interface for building Tauri apps", + "type": "commonjs", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/tauri-apps/tauri.git" + }, + "contributors": [ + "Tauri Programme within The Commons Conservancy" + ], + "license": "Apache-2.0 OR MIT", + "bugs": { + "url": "https://github.com/tauri-apps/tauri/issues" + }, + "homepage": "https://github.com/tauri-apps/tauri#readme", + "publishConfig": { + "access": "public" + }, + "main": "main.js", + "types": "main.d.ts", + "napi": { + "binaryName": "cli", + "targets": [ + "x86_64-unknown-linux-gnu", + "x86_64-pc-windows-msvc", + "x86_64-apple-darwin", + "aarch64-apple-darwin", + "aarch64-unknown-linux-gnu", + "aarch64-unknown-linux-musl", + "armv7-unknown-linux-gnueabihf", + "x86_64-unknown-linux-musl", + "riscv64gc-unknown-linux-gnu", + "i686-pc-windows-msvc", + "aarch64-pc-windows-msvc" + ] + }, + "devDependencies": { + "@napi-rs/cli": "^3.4.1", + "@types/node": "^24.0.0", + "cross-env": "10.1.0", + "vitest": "^4.0.0" + }, + "engines": { + "node": ">= 10" + }, + "bin": { + "tauri": "./tauri.js" + }, + "scripts": { + "artifacts": "napi artifacts", + "build": "cross-env TARGET=node napi build --platform --profile release-size-optimized", + "postbuild": "node append-headers.js", + "build:debug": "cross-env TARGET=node napi build --platform", + "postbuild:debug": "node append-headers.js", + "prepublishOnly": "napi prepublish -t npm --gh-release-id $RELEASE_ID", + "prepack": "cp ../../crates/tauri-schema-generator/schemas/config.schema.json .", + "version": "napi version", + "test": "vitest run", + "tauri": "node ./tauri.js" + }, + "optionalDependencies": { + "@tauri-apps/cli-linux-x64-gnu": "2.9.6", + "@tauri-apps/cli-win32-x64-msvc": "2.9.6", + "@tauri-apps/cli-darwin-x64": "2.9.6", + "@tauri-apps/cli-darwin-arm64": "2.9.6", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", + "@tauri-apps/cli-linux-arm64-musl": "2.9.6", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", + "@tauri-apps/cli-linux-x64-musl": "2.9.6", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.6" + } +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/@tauri-apps/cli/tauri.js b/tools/join-backups/node_modules/@tauri-apps/cli/tauri.js new file mode 100644 index 0000000..d046057 --- /dev/null +++ b/tools/join-backups/node_modules/@tauri-apps/cli/tauri.js @@ -0,0 +1,57 @@ +#!/usr/bin/env node + +// Copyright 2019-2024 Tauri Programme within The Commons Conservancy +// SPDX-License-Identifier: Apache-2.0 +// SPDX-License-Identifier: MIT + +const cli = require('./main') +const path = require('path') + +const [bin, script, ...args] = process.argv +const binStem = path.parse(bin).name.toLowerCase() + +// We want to make a helpful binary name for the underlying CLI helper, if we +// can successfully detect what command likely started the execution. +let binName + +// deno run -A npm:@tauri-apps/cli or deno task tauri +if (globalThis.navigator?.userAgent?.includes('Deno')) { + binName = bin +} +// Even if started by a package manager, the binary will be NodeJS. +// Some distribution still use "nodejs" as the binary name. +else if (binStem.match(/(nodejs|node|bun)\-?([0-9]*)*$/g)) { + const managerStem = process.env.npm_execpath + ? path.parse(process.env.npm_execpath).name.toLowerCase() + : null + if (managerStem) { + let manager + switch (managerStem) { + // Only supported package manager that has a different filename is npm. + case 'npm-cli': + manager = 'npm' + break + + // Yarn, pnpm, and bun have the same stem name as their bin. + // We assume all unknown package managers do as well. + default: + manager = managerStem + break + } + + binName = `${manager} run ${process.env.npm_lifecycle_event}` + } else { + // Assume running NodeJS if we didn't detect a manager from the env. + // We normalize the path to prevent the script's absolute path being used. + const scriptNormal = path.normalize(path.relative(process.cwd(), script)) + binName = `${binStem} ${scriptNormal}` + } +} else { + // We don't know what started it, assume it's already stripped. + args.unshift(bin) +} + +cli.run(args, binName).catch((err) => { + cli.logError(err.message) + process.exit(1) +}) diff --git a/tools/join-backups/node_modules/fast-xml-parser/CHANGELOG.md b/tools/join-backups/node_modules/fast-xml-parser/CHANGELOG.md new file mode 100644 index 0000000..017e5d9 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/CHANGELOG.md @@ -0,0 +1,606 @@ +Note: If you find missing information about particular minor version, that version must have been changed without any functional change in this library. + +**4.5.2 / 2025-02-18** +- Fix null CDATA to comply with undefined behavior (#701) (By [Matthieu BOHEAS](https://github.com/Kelgors)) +- Fix(performance): Update check for leaf node in saveTextToParentTag function in OrderedObjParser.js (#707) (By [...](https://github.com/tomingtoming)) +- Fix: emit full JSON string from CLI when no output filename specified (#710) (By [Matt Benson](https://github.com/mbenson)) + +**4.5.1 / 2024-12-15** +- Fix empty tag key name for v5 (#697). no impact on v4 +- Fixes entity parsing when used in strict mode (#699) + +**4.5.0 / 2024-09-03** +- feat #666: ignoreAttributes support function, and array of string or regex (By [ArtemM](https://github.com/mav-rik)) + +**4.4.1 / 2024-07-28** +- v5 fix: maximum length limit to currency value +- fix #634: build attributes with oneListGroup and attributesGroupName (#653)(By [Andreas Naziris](https://github.com/a-rasin)) +- fix: get oneListGroup to work as expected for array of strings (#662)(By [Andreas Naziris](https://github.com/a-rasin)) + +**4.4.0 / 2024-05-18** +- fix #654: parse attribute list correctly for self closing stop node. +- fix: validator bug when closing tag is not opened. (#647) (By [Ryosuke Fukatani](https://github.com/RyosukeFukatani)) +- fix #581: typings; return type of `tagValueProcessor` & `attributeValueProcessor` (#582) (By [monholm]()) + +**4.3.6 / 2024-03-16** +- Add support for parsing HTML numeric entities (#645) (By [Jonas Schade ](https://github.com/DerZade)) + +**4.3.5 / 2024-02-24** +- code for v5 is added for experimental use + +**4.3.4 / 2024-01-10** +- fix: Don't escape entities in CDATA sections (#633) (By [wackbyte](https://github.com/wackbyte)) + +**4.3.3 / 2024-01-10** +- Remove unnecessary regex + +**4.3.2 / 2023-10-02** +- fix `jObj.hasOwnProperty` when give input is null (By [Arda TANRIKULU](https://github.com/ardatan)) + +**4.3.1 / 2023-09-24** +- revert back "Fix typings for builder and parser to make return type generic" to avoid failure of existing projects. Need to decide a common approach. + +**4.3.0 / 2023-09-20** +- Fix stopNodes to work with removeNSPrefix (#607) (#608) (By [Craig Andrews]https://github.com/candrews)) +- Fix #610 ignore properties set to Object.prototype +- Fix typings for builder and parser to make return type generic (By [Sarah Dayan](https://github.com/sarahdayan)) + +**4.2.7 / 2023-07-30** +- Fix: builder should set text node correctly when only textnode is present (#589) (By [qianqing](https://github.com/joneqian)) +- Fix: Fix for null and undefined attributes when building xml (#585) (#598). A null or undefined value should be ignored. (By [Eugenio Ceschia](https://github.com/cecia234)) + +**4.2.6 / 2023-07-17** +- Fix: Remove trailing slash from jPath for self-closing tags (#595) (By [Maciej Radzikowski](https://github.com/m-radzikowski)) + +**4.2.5 / 2023-06-22** +- change code implementation + +**4.2.4 / 2023-06-06** +- fix security bug + +**4.2.3 / 2023-06-05** +- fix security bug + +**4.2.2 / 2023-04-18** +- fix #562: fix unpaired tag when it comes in last of a nested tag. Also throw error when unpaired tag is used as closing tag + +**4.2.1 / 2023-04-18** +- fix: jpath after unpaired tags + +**4.2.0 / 2023-04-09** +- support `updateTag` parser property + +**4.1.4 / 2023-04-08** +- update typings to let user create XMLBuilder instance without options (#556) (By [Patrick](https://github.com/omggga)) +- fix: IsArray option isn't parsing tags with 0 as value correctly #490 (#557) (By [Aleksandr Murashkin](https://github.com/p-kuen)) +- feature: support `oneListGroup` to group repeated children tags udder single group + +**4.1.3 / 2023-02-26** +- fix #546: Support complex entity value + +**4.1.2 / 2023-02-12** +- Security Fix + +**4.1.1 / 2023-02-03** +- Fix #540: ignoreAttributes breaks unpairedTags +- Refactor XML builder code + +**4.1.0 / 2023-02-02** +- Fix '<' or '>' in DTD comment throwing an error. (#533) (By [Adam Baker](https://github.com/Cwazywierdo)) +- Set "eNotation" to 'true' as default + +**4.0.15 / 2023-01-25** +- make "eNotation" optional + +**4.0.14 / 2023-01-22** +- fixed: add missed typing "eNotation" to parse values + +**4.0.13 / 2023-01-07** +- preserveorder formatting (By [mdeknowis](https://github.com/mdeknowis)) +- support `transformAttributeName` (By [Erik Rothoff Andersson](https://github.com/erkie)) + +**4.0.12 / 2022-11-19** +- fix typescript + +**4.0.11 / 2022-10-05** +- fix #501: parse for entities only once + +**4.0.10 / 2022-09-14** +- fix broken links in demo site (By [Yannick Lang](https://github.com/layaxx)) +- fix #491: tagValueProcessor type definition (By [Andrea Francesco Speziale](https://github.com/andreafspeziale)) +- Add jsdocs for tagValueProcessor + + +**4.0.9 / 2022-07-10** +- fix #470: stop-tag can have self-closing tag with same name +- fix #472: stopNode can have any special tag inside +- Allow !ATTLIST and !NOTATION with DOCTYPE +- Add transformTagName option to transform tag names when parsing (#469) (By [Erik Rothoff Andersson](https://github.com/erkie)) + +**4.0.8 / 2022-05-28** +- Fix CDATA parsing returning empty string when value = 0 (#451) (By [ndelanou](https://github.com/ndelanou)) +- Fix stopNodes when same tag appears inside node (#456) (By [patrickshipe](https://github.com/patrickshipe)) +- fix #468: prettify own properties only + +**4.0.7 / 2022-03-18** +- support CDATA even if tag order is not preserved +- support Comments even if tag order is not preserved +- fix #446: XMLbuilder should not indent XML declaration + +**4.0.6 / 2022-03-08** +- fix: call tagValueProcessor only once for array items +- fix: missing changed for #437 + +**4.0.5 / 2022-03-06** +- fix #437: call tagValueProcessor from XML builder + +**4.0.4 / 2022-03-03** +- fix #435: should skip unpaired and self-closing nodes when set as stopnodes + +**4.0.3 / 2022-02-15** +- fix: ReferenceError when Bundled with Strict (#431) (By [Andreas Heissenberger](https://github.com/aheissenberger)) + + +**4.0.2 / 2022-02-04** +- builder supports `suppressUnpairedNode` +- parser supports `ignoreDeclaration` and `ignorePiTags` +- fix: when comment is parsed as text value if given as ` ...` #423 +- builder supports decoding `&` + +**4.0.1 / 2022-01-08** +- fix builder for pi tag +- fix: support suppressBooleanAttrs by builder + +**4.0.0 / 2022-01-06** +- Generating different combined, parser only, builder only, validator only browser bundles +- Keeping cjs modules as they can be imported in cjs and esm modules both. Otherwise refer `esm` branch. + +**4.0.0-beta.8 / 2021-12-13** +- call tagValueProcessor for stop nodes + +**4.0.0-beta.7 / 2021-12-09** +- fix Validator bug when an attribute has no value but '=' only +- XML Builder should suppress unpaired tags by default. +- documents update for missing features +- refactoring to use Object.assign +- refactoring to remove repeated code + +**4.0.0-beta.6 / 2021-12-05** +- Support PI Tags processing +- Support `suppressBooleanAttributes` by XML Builder for attributes with value `true`. + +**4.0.0-beta.5 / 2021-12-04** +- fix: when a tag with name "attributes" + +**4.0.0-beta.4 / 2021-12-02** +- Support HTML document parsing +- skip stop nodes parsing when building the XML from JS object +- Support external entites without DOCTYPE +- update dev dependency: strnum v1.0.5 to fix long number issue + +**4.0.0-beta.3 / 2021-11-30** +- support global stopNodes expression like "*.stop" +- support self-closing and paired unpaired tags +- fix: CDATA should not be parsed. +- Fix typings for XMLBuilder (#396)(By [Anders Emil Salvesen](https://github.com/andersem)) +- supports XML entities, HTML entities, DOCTYPE entities + +**⚠️ 4.0.0-beta.2 / 2021-11-19** +- rename `attrMap` to `attibutes` in parser output when `preserveOrder:true` +- supports unpairedTags + +**⚠️ 4.0.0-beta.1 / 2021-11-18** +- Parser returns an array now + - to make the structure common + - and to return root level detail +- renamed `cdataTagName` to `cdataPropName` +- Added `commentPropName` +- fix typings + +**⚠️ 4.0.0-beta.0 / 2021-11-16** +- Name change of many configuration properties. + - `attrNodeName` to `attributesGroupName` + - `attrValueProcessor` to `attributeValueProcessor` + - `parseNodeValue` to `parseTagValue` + - `ignoreNameSpace` to `removeNSPrefix` + - `numParseOptions` to `numberParseOptions` + - spelling correction for `suppressEmptyNode` +- Name change of cli and browser bundle to **fxparser** +- `isArray` option is added to parse a tag into array +- `preserveOrder` option is added to render XML in such a way that the result js Object maintains the order of properties same as in XML. +- Processing behaviour of `tagValueProcessor` and `attributeValueProcessor` are changes with extra input parameters +- j2xparser is renamed to XMLBuilder. +- You need to build XML parser instance for given options first before parsing XML. +- fix #327, #336: throw error when extra text after XML content +- fix #330: attribute value can have '\n', +- fix #350: attrbiutes can be separated by '\n' from tagname + +3.21.1 / 2021-10-31 +- Correctly format JSON elements with a text prop but no attribute props ( By [haddadnj](https://github.com/haddadnj) ) + +3.21.0 / 2021-10-25 + - feat: added option `rootNodeName` to set tag name for array input when converting js object to XML. + - feat: added option `alwaysCreateTextNode` to force text node creation (by: *@massimo-ua*) + - ⚠️ feat: Better error location for unclosed tags. (by *@Gei0r*) + - Some error messages would be changed when validating XML. Eg + - `{ InvalidXml: "Invalid '[ \"rootNode\"]' found." }` → `{InvalidTag: "Unclosed tag 'rootNode'."}` + - `{ InvalidTag: "Closing tag 'rootNode' is expected inplace of 'rootnode'." }` → `{ InvalidTag: "Expected closing tag 'rootNode' (opened in line 1) instead of closing tag 'rootnode'."}` + - ⚠️ feat: Column in error response when validating XML +```js +{ + "code": "InvalidAttr", + "msg": "Attribute 'abc' is repeated.", + "line": 1, + "col": 22 +} +``` + +3.20.1 / 2021-09-25 + - update strnum package + +3.20.0 / 2021-09-10 + - Use strnum npm package to parse string to number + - breaking change: long number will be parsed to scientific notation. + +3.19.0 / 2021-03-14 + - License changed to MIT original + - Fix #321 : namespace tag parsing + +3.18.0 / 2021-02-05 + - Support RegEx and function in arrayMode option + - Fix #317 : validate nested PI tags + +3.17.4 / 2020-06-07 + - Refactor some code to support IE11 + - Fix: `` space as attribute string + +3.17.3 / 2020-05-23 + - Fix: tag name separated by \n \t + - Fix: throw error for unclosed tags + +3.17.2 / 2020-05-23 + - Fixed an issue in processing doctype tag + - Fixed tagName where it should not have whitespace chars + +3.17.1 / 2020-05-19 + - Fixed an issue in checking opening tag + +3.17.0 / 2020-05-18 + - parser: fix '<' issue when it comes in aatr value + - parser: refactoring to remove dependency from regex + - validator: fix IE 11 issue for error messages + - updated dev dependencies + - separated benchmark module to sub-module + - breaking change: comments will not be removed from CDATA data + +3.16.0 / 2020-01-12 + - validaor: fix for ampersand characters (#215) + - refactoring to support unicode chars in tag name + - update typing for validator error + +3.15.1 / 2019-12-09 + - validaor: fix multiple roots are not allowed + +3.15.0 / 2019-11-23 + - validaor: improve error messaging + - validator: add line number in case of error + - validator: add more error scenarios to make it more descriptive + +3.14.0 / 2019-10-25 + - arrayMode for XML to JS obj parsing + +3.13.0 / 2019-10-02 + - pass tag/attr name to tag/attr value processor + - inbuilt optional validation with XML parser + +3.12.21 / 2019-10-02 + - Fix validator for unclosed XMLs + - move nimnjs dependency to dev dependency + - update dependencies + +3.12.20 / 2019-08-16 + - Revert: Fix #167: '>' in attribute value as it is causing high performance degrade. + +3.12.19 / 2019-07-28 + - Fix js to xml parser should work for date values. (broken: `tagValueProcessor` will receive the original value instead of string always) (breaking change) + +3.12.18 / 2019-07-27 + - remove configstore dependency + +3.12.17 / 2019-07-14 + - Fix #167: '>' in attribute value + +3.12.16 / 2019-03-23 + - Support a new option "stopNodes". (#150) +Accept the list of tags which are not required to be parsed. Instead, all the nested tag and data will be assigned as string. + - Don't show post-install message + +3.12.12 / 2019-01-11 + - fix : IE parseInt, parseFloat error + +3.12.11 / 2018-12-24 + - fix #132: "/" should not be parsed as boolean attr in case of self closing tags + +3.12.9 / 2018-11-23 + - fix #129 : validator should not fail when an atrribute name is 'length' + +3.12.8 / 2018-11-22 + - fix #128 : use 'attrValueProcessor' to process attribute value in json2xml parser + +3.12.6 / 2018-11-10 + - Fix #126: check for type + +3.12.4 / 2018-09-12 + - Fix: include tasks in npm package + +3.12.3 / 2018-09-12 + - Fix CLI issue raised in last PR + +3.12.2 / 2018-09-11 + - Fix formatting for JSON to XML output + - Migrate to webpack (PR merged) + - fix cli (PR merged) + +3.12.0 / 2018-08-06 + - Support hexadecimal values + - Support true number parsing + +3.11.2 / 2018-07-23 + - Update Demo for more options + - Update license information + - Update readme for formatting, users, and spelling mistakes + - Add missing typescript definition for j2xParser + - refactoring: change filenames + +3.11.1 / 2018-06-05 + - fix #93: read the text after self closing tag + +3.11.0 / 2018-05-20 + - return defaultOptions if there are not options in buildOptions function + - added localeRange declaration in parser.d.ts + - Added support of cyrillic characters in validator XML + - fixed bug in validator work when XML data with byte order marker + +3.10.0 / 2018-05-13 + - Added support of cyrillic characters in parsing XML to JSON + +3.9.11 / 2018-05-09 + - fix https://github.com/NaturalIntelligence/fast-xml-parser/issues/80 fix nimn chars + - update package information + - fix https://github.com/NaturalIntelligence/fast-xml-parser/issues/86: json 2 xml parser : property with null value should be parsed to self closing tag. + - update online demo + - revert zombiejs to old version to support old version of node + - update dependencies + +3.3.10 / 2018-04-23 + - fix #77 : parse even if closing tag has space before '>' + - include all css & js lib in demo app + - remove babel dependencies until needed + +3.3.9 / 2018-04-18 + - fix #74 : TS2314 TypeScript compiler error + +3.3.8 / 2018-04-17 + - fix #73 : IE doesn't support Object.assign + +3.3.7 / 2018-04-14 + - fix: use let insted of const in for loop of validator + - Merge pull request + https://github.com/NaturalIntelligence/fast-xml-parser/issues/71 from bb/master + first draft of typings for typescript + https://github.com/NaturalIntelligence/fast-xml-parser/issues/69 + - Merge pull request + https://github.com/NaturalIntelligence/fast-xml-parser/issues/70 from bb/patch-1 + fix some typos in readme + +3.3.6 / 2018-03-21 + - change arrow functions to full notation for IE compatibility + +3.3.5 / 2018-03-15 + - fix https://github.com/NaturalIntelligence/fast-xml-parser/issues/67 : attrNodeName invalid behavior + - fix: remove decodeHTML char condition + +3.3.4 / 2018-03-14 + - remove dependency on "he" package + - refactor code to separate methods in separate files. + - draft code for transforming XML to json string. It is not officially documented due to performance issue. + +3.3.0 / 2018-03-05 + - use common default options for XML parsing for consistency. And add `parseToNimn` method. + - update nexttodo + - update README about XML to Nimn transformation and remove special notes about 3.x release + - update CONTRIBUTING.ms mentioning nexttodo + - add negative case for XML PIs + - validate xml processing instruction tags https://github.com/NaturalIntelligence/fast-xml-parser/issues/62 + - nimndata: handle array with object + - nimndata: node with nested node and text node + - nimndata: handle attributes and text node + - nimndata: add options, handle array + - add xml to nimn data converter + - x2j: direct access property with tagname + - update changelog + - fix validator when single quote presents in value enclosed with double quotes or vice versa + - Revert "remove unneded nimnjs dependency, move opencollective to devDependencies and replace it + with more light opencollective-postinstall" + This reverts commit d47aa7181075d82db4fee97fd8ea32b056fe3f46. + - Merge pull request: https://github.com/NaturalIntelligence/fast-xml-parser/issues/63 from HaroldPutman/suppress-undefined + Keep undefined nodes out of the XML output : This is useful when you are deleting nodes from the JSON and rewriting XML. + +3.2.4 / 2018-03-01 + - fix #59 fix in validator when open quote presents in attribute value + - Create nexttodo.md + - exclude static from bitHound tests + - add package lock + +3.2.3 / 2018-02-28 + - Merge pull request from Delagen/master: fix namespaces can contain the same characters as xml names + +3.2.2 / 2018-02-22 + - fix: attribute xmlns should not be removed if ignoreNameSpace is false + - create CONTRIBUTING.md + +3.2.1 / 2018-02-17 + - fix: empty attribute should be parsed + +3.2.0 / 2018-02-16 + - Merge pull request : Dev to Master + - Update README and version + - j2x:add performance test + - j2x: Remove extra empty line before closing tag + - j2x: suppress empty nodes to self closing node if configured + - j2x: provide option to give indentation depth + - j2x: make optional formatting + - j2x: encodeHTMLchat + - j2x: handle cdata tag + - j2x: handle grouped attributes + - convert json to xml + - nested object + - array + - attributes + - text value + - small refactoring + - Merge pull request: Update cli.js to let user validate XML file or data + - Add option for rendering CDATA as separate property + +3.0.1 / 2018-02-09 + - fix CRLF: replace it with single space in attributes value only. + +3.0.0 / 2018-02-08 + - change online tool with new changes + - update info about new options + - separate tag value processing to separate function + - make HTML decoding optional + - give an option to allow boolean attributes + - change cli options as per v3 + - Correct comparison table format on README + - update v3 information + - some performance improvement changes + - Make regex object local to the method and move some common methods to util + - Change parser to + - handle multiple instances of CDATA + - make triming of value optionals + - HTML decode attribute and text value + - refactor code to separate files + - Ignore newline chars without RE (in validator) + - validate for XML prolog + - Validate DOCTYPE without RE + - Update validator to return error response + - Update README to add detail about V3 + - Separate xmlNode model class + - include vscode debug config + - fix for repeated object + - fix attribute regex for boolean attributes + - Fix validator for invalid attributes +2.9.4 / 2018-02-02 + - Merge pull request: Decode HTML characters + - refactor source folder name + - ignore bundle / browser js to be published to npm +2.9.3 / 2018-01-26 + - Merge pull request: Correctly remove CRLF line breaks + - Enable to parse attribute in online editor + - Fix testing demo app test + - Describe parsing options + - Add options for online demo +2.9.2 / 2018-01-18 + - Remove check if tag starting with "XML" + - Fix: when there are spaces before / after CDATA + +2.9.1 / 2018-01-16 + - Fix: newline should be replaced with single space + - Fix: for single and multiline comments + - validate xml with CDATA + - Fix: the issue when there is no space between 2 attributes + - Fix: https://github.com/NaturalIntelligence/fast-xml-parser/issues/33: when there is newline char in attr val, it doesn't parse + - Merge pull request: fix ignoreNamespace + - fix: don't wrap attributes if only namespace attrs + - fix: use portfinder for run tests, update deps + - fix: don't treat namespaces as attributes when ignoreNamespace enabled + +2.9.0 / 2018-01-10 + - Rewrite the validator to handle large files. + Ignore DOCTYPE validation. + - Fix: When attribute value has equal sign + +2.8.3 / 2017-12-15 + - Fix: when a tag has value along with subtags + +2.8.2 / 2017-12-04 + - Fix value parsing for IE + +2.8.1 / 2017-12-01 + - fix: validator should return false instead of err when invalid XML + +2.8.0 / 2017-11-29 + - Add CLI option to ignore value conversion + - Fix variable name when filename is given on CLI + - Update CLI help text + - Merge pull request: xml2js: Accept standard input + - Test Node 8 + - Update dependencies + - Bundle readToEnd + - Add ability to read from standard input + +2.7.4 / 2017-09-22 + - Merge pull request: Allow wrap attributes with subobject to compatible with other parsers output + +2.7.3 / 2017-08-02 + - fix: handle CDATA with regx + +2.7.2 / 2017-07-30 + - Change travis config for yarn caching + - fix validator: when tag property is same as array property + - Merge pull request: Failing test case in validator for valid SVG + +2.7.1 / 2017-07-26 + - Fix: Handle val 0 + +2.7.0 / 2017-07-25 + - Fix test for arrayMode + - Merge pull request: Add arrayMode option to parse any nodes as arrays + +2.6.0 / 2017-07-14 + - code improvement + - Add unit tests for value conversion for attr + - Merge pull request: option of an attribute value conversion to a number (textAttrConversion) the same way as the textNodeConversion option does. Default value is false. + +2.5.1 / 2017-07-01 + - Fix XML element name pattern + - Fix XML element name pattern while parsing + - Fix validation for xml tag element + +2.5.0 / 2017-06-25 + - Improve Validator performance + - update attr matching regex + - Add perf tests + - Improve atrr regex to handle all cases + +2.4.4 / 2017-06-08 + - Bug fix: when an attribute has single or double quote in value + +2.4.3 / 2017-06-05 + - Bug fix: when multiple CDATA tags are given + - Merge pull request: add option "textNodeConversion" + - add option "textNodeConversion" + +2.4.1 / 2017-04-14 + - fix tests + - Bug fix: preserve initial space of node value + - Handle CDATA + +2.3.1 / 2017-03-15 + - Bug fix: when single self closing tag + - Merge pull request: fix .codeclimate.yml + - Update .codeclimate.yml - Fixed config so it does not error anymore. + - Update .codeclimate.yml + +2.3.0 / 2017-02-26 + - Code improvement + - add bithound config + - Update usage + - Update travis to generate bundle js before running tests + - 1.Browserify, 2. add more tests for validator + - Add validator + - Fix CLI default parameter bug + +2.2.1 / 2017-02-05 + - Bug fix: CLI default option diff --git a/tools/join-backups/node_modules/fast-xml-parser/LICENSE b/tools/join-backups/node_modules/fast-xml-parser/LICENSE new file mode 100644 index 0000000..d7da622 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Amit Kumar Gupta + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/join-backups/node_modules/fast-xml-parser/README.md b/tools/join-backups/node_modules/fast-xml-parser/README.md new file mode 100644 index 0000000..22f2ddf --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/README.md @@ -0,0 +1,237 @@ +# [fast-xml-parser](https://www.npmjs.com/package/fast-xml-parser) +[![NPM quality][quality-image]][quality-url] +[![Coverage Status](https://coveralls.io/repos/github/NaturalIntelligence/fast-xml-parser/badge.svg?branch=master)](https://coveralls.io/github/NaturalIntelligence/fast-xml-parser?branch=master) +[Try me](https://naturalintelligence.github.io/fast-xml-parser/) +[![NPM total downloads](https://img.shields.io/npm/dt/fast-xml-parser.svg)](https://npm.im/fast-xml-parser) + + +Validate XML, Parse XML to JS Object, or Build XML from JS Object without C/C++ based libraries and no callback. + +--- + +Checkout our new library [Text2Chart](https://solothought.com/text2chart/flow) that constructs flow chart out of simple text. Very helpful in creating or alayzing an algorithm, and documentation purpose +
+ +Sponsor this project + + + + + + + + donate button +
+
+
+ + + +![fxp_sponsors](https://raw.githubusercontent.com/NaturalIntelligence/ThankYouBackers/main/assets/NI_sponsors.jpg) +- Hiroki Kokubun + +> This is a donation. No goods or services are expected in return. Any requests for refunds for those purposes will be rejected. +## Users + + + + + + + + + + + + + + + + + + + +[more](./USERs.md) + +The list of users are mostly published by Github or communicated directly. Feel free to contact if you find any information wrong. + +--- + +## Main Features + +FXP logo + +* Validate XML data syntactically +* Parse XML to JS Object +* Build XML from JS Object +* Compatible to node js packages, in browser, and in CLI (click try me button above for demo) +* Faster than any other pure JS implementation. +* It can handle big files (tested up to 100mb). +* Controlled parsing using various options +* XML Entities, HTML entities, and DOCTYPE entites are supported. +* unpaired tags (Eg `
` in HTML), stop nodes (Eg ` +: + +``` + +Bundle size + +| Bundle Name | Size | +| ------------------ | ---- | +| fxbuilder.min.js | 6.5K | +| fxparser.min.js | 20K | +| fxp.min.js | 26K | +| fxvalidator.min.js | 5.7K | + +### Documents + + + + + + + +
v3v4v5
+ documents +
    +
  1. Getting Started
  2. +
  3. XML Parser
  4. +
  5. XML Builder
  6. +
  7. XML Validator
  8. +
  9. Entities
  10. +
  11. HTML Document Parsing
  12. +
  13. PI Tag processing
  14. +
    +
  1. Getting Started +
  2. Features
  3. +
  4. Options
  5. +
  6. Output Builders
  7. +
  8. Value Parsers
  9. +
+ +**note**: version 5 is released with version 4 tfor experimental use. Based on it's demand, it'll be developed and the features can be different in final release. + +## Performance +negative means error + +### XML Parser + + + + +* Y-axis: requests per second +* X-axis: File size + +### XML Builder + + +* Y-axis: requests per second + + + + + + +## Usage Trend + +[Usage Trend of fast-xml-parser](https://npm-compare.com/fast-xml-parser#timeRange=THREE_YEARS) + + + NPM Usage Trend of fast-xml-parser + + +## Supporters +### Contributors + +This project exists thanks to [all](graphs/contributors) the people who contribute. [[Contribute](docs/CONTRIBUTING.md)]. + + + + +### Backers + +Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/fast-xml-parser#backer)] + + + + + +# License +* MIT License + +![Donate $5](static/img/donation_quote.png) diff --git a/tools/join-backups/node_modules/fast-xml-parser/package.json b/tools/join-backups/node_modules/fast-xml-parser/package.json new file mode 100644 index 0000000..285ff12 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/package.json @@ -0,0 +1,72 @@ +{ + "name": "fast-xml-parser", + "version": "4.5.3", + "description": "Validate XML, Parse XML, Build XML without C/C++ based libraries", + "main": "./src/fxp.js", + "scripts": { + "test": "nyc --reporter=lcov --reporter=text jasmine spec/*spec.js", + "test-types": "tsc --noEmit spec/typings/typings-test.ts", + "unit": "jasmine", + "coverage": "nyc report --reporter html --reporter text -t .nyc_output --report-dir .nyc_output/summary", + "perf": "node ./benchmark/perfTest3.js", + "lint": "eslint src/*.js spec/*.js", + "bundle": "webpack --config webpack-prod.config.js", + "prettier": "prettier --write src/**/*.js", + "publish-please": "publish-please", + "checkReadiness": "publish-please --dry-run" + }, + "bin": { + "fxparser": "./src/cli/cli.js" + }, + "repository": { + "type": "git", + "url": "https://github.com/NaturalIntelligence/fast-xml-parser" + }, + "keywords": [ + "fast", + "xml", + "json", + "parser", + "xml2js", + "x2js", + "xml2json", + "js", + "cli", + "validator", + "validate", + "transformer", + "assert", + "js2xml", + "json2xml", + "html" + ], + "author": "Amit Gupta (https://solothought.com)", + "license": "MIT", + "devDependencies": { + "@babel/core": "^7.13.10", + "@babel/plugin-transform-runtime": "^7.13.10", + "@babel/preset-env": "^7.13.10", + "@babel/register": "^7.13.8", + "@types/node": "20", + "babel-loader": "^8.2.2", + "eslint": "^8.3.0", + "he": "^1.2.0", + "jasmine": "^3.6.4", + "nyc": "^15.1.0", + "prettier": "^1.19.1", + "publish-please": "^5.5.2", + "typescript": "5", + "webpack": "^5.64.4", + "webpack-cli": "^4.9.1" + }, + "typings": "src/fxp.d.ts", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "dependencies": { + "strnum": "^1.1.1" + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/cli/cli.js b/tools/join-backups/node_modules/fast-xml-parser/src/cli/cli.js new file mode 100644 index 0000000..2bc0cd6 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/cli/cli.js @@ -0,0 +1,93 @@ +#!/usr/bin/env node +'use strict'; +/*eslint-disable no-console*/ +const fs = require('fs'); +const path = require('path'); +const {XMLParser, XMLValidator} = require("../fxp"); +const readToEnd = require('./read').readToEnd; + +const version = require('./../../package.json').version; +if (process.argv[2] === '--help' || process.argv[2] === '-h') { + console.log(require("./man")); +} else if (process.argv[2] === '--version') { + console.log(version); +} else { + const options = { + removeNSPrefix: true, + ignoreAttributes: false, + parseTagValue: true, + parseAttributeValue: true, + }; + let fileName = ''; + let outputFileName; + let validate = false; + let validateOnly = false; + for (let i = 2; i < process.argv.length; i++) { + if (process.argv[i] === '-ns') { + options.removeNSPrefix = false; + } else if (process.argv[i] === '-a') { + options.ignoreAttributes = true; + } else if (process.argv[i] === '-c') { + options.parseTagValue = false; + options.parseAttributeValue = false; + } else if (process.argv[i] === '-o') { + outputFileName = process.argv[++i]; + } else if (process.argv[i] === '-v') { + validate = true; + } else if (process.argv[i] === '-V') { + validateOnly = true; + } else { + //filename + fileName = process.argv[i]; + } + } + + const callback = function(xmlData) { + let output = ''; + if (validate) { + const parser = new XMLParser(options); + output = parser.parse(xmlData,validate); + } else if (validateOnly) { + output = XMLValidator.validate(xmlData); + process.exitCode = output === true ? 0 : 1; + } else { + const parser = new XMLParser(options); + output = JSON.stringify(parser.parse(xmlData,validate), null, 4); + } + if (outputFileName) { + writeToFile(outputFileName, output); + } else { + console.log(JSON.stringify(output, null, 2)); + } + }; + + try { + + if (!fileName) { + readToEnd(process.stdin, function(err, data) { + if (err) { + throw err; + } + callback(data.toString()); + }); + } else { + fs.readFile(fileName, function(err, data) { + if (err) { + throw err; + } + callback(data.toString()); + }); + } + } catch (e) { + console.log('Seems an invalid file or stream.' + e); + } +} + +function writeToFile(fileName, data) { + fs.writeFile(fileName, data, function(err) { + if (err) { + throw err; + } + console.log('JSON output has been written to ' + fileName); + }); +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/cli/man.js b/tools/join-backups/node_modules/fast-xml-parser/src/cli/man.js new file mode 100644 index 0000000..89947cc --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/cli/man.js @@ -0,0 +1,12 @@ +module.exports = `Fast XML Parser 4.0.0 +---------------- +$ fxparser [-ns|-a|-c|-v|-V] [-o outputfile.json] +$ cat xmlfile.xml | fxparser [-ns|-a|-c|-v|-V] [-o outputfile.json] + +Options +---------------- +-ns: remove namespace from tag and atrribute name. +-a: don't parse attributes. +-c: parse values to premitive type. +-v: validate before parsing. +-V: validate only.` \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/cli/read.js b/tools/join-backups/node_modules/fast-xml-parser/src/cli/read.js new file mode 100644 index 0000000..642da52 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/cli/read.js @@ -0,0 +1,92 @@ +'use strict'; + +// Copyright 2013 Timothy J Fontaine +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE + +/* + +Read any stream all the way to the end and trigger a single cb + +const http = require('http'); + +const rte = require('readtoend'); + +http.get('http://nodejs.org', function(response) { + rte.readToEnd(response, function(err, body) { + console.log(body); + }); +}); + +*/ + +let stream = require('stream'); +const util = require('util'); + +if (!stream.Transform) { + stream = require('readable-stream'); +} + +function ReadToEnd(opts) { + if (!(this instanceof ReadToEnd)) { + return new ReadToEnd(opts); + } + + stream.Transform.call(this, opts); + + this._rte_encoding = opts.encoding || 'utf8'; + + this._buff = ''; +} + +module.exports = ReadToEnd; +util.inherits(ReadToEnd, stream.Transform); + +ReadToEnd.prototype._transform = function(chunk, encoding, done) { + this._buff += chunk.toString(this._rte_encoding); + this.push(chunk); + done(); +}; + +ReadToEnd.prototype._flush = function(done) { + this.emit('complete', undefined, this._buff); + done(); +}; + +ReadToEnd.readToEnd = function(stream, options, cb) { + if (!cb) { + cb = options; + options = {}; + } + + const dest = new ReadToEnd(options); + + stream.pipe(dest); + + stream.on('error', function(err) { + stream.unpipe(dest); + cb(err); + }); + + dest.on('complete', cb); + + dest.resume(); + + return dest; +}; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/fxp.d.ts b/tools/join-backups/node_modules/fast-xml-parser/src/fxp.d.ts new file mode 100644 index 0000000..7a48b9d --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/fxp.d.ts @@ -0,0 +1,418 @@ +type X2jOptions = { + /** + * Preserve the order of tags in resulting JS object + * + * Defaults to `false` + */ + preserveOrder?: boolean; + + /** + * Give a prefix to the attribute name in the resulting JS object + * + * Defaults to '@_' + */ + attributeNamePrefix?: string; + + /** + * A name to group all attributes of a tag under, or `false` to disable + * + * Defaults to `false` + */ + attributesGroupName?: false | string; + + /** + * The name of the next node in the resulting JS + * + * Defaults to `#text` + */ + textNodeName?: string; + + /** + * Whether to ignore attributes when parsing + * + * When `true` - ignores all the attributes + * + * When `false` - parses all the attributes + * + * When `Array` - filters out attributes that match provided patterns + * + * When `Function` - calls the function for each attribute and filters out those for which the function returned `true` + * + * Defaults to `true` + */ + ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPath: string) => boolean); + + /** + * Whether to remove namespace string from tag and attribute names + * + * Defaults to `false` + */ + removeNSPrefix?: boolean; + + /** + * Whether to allow attributes without value + * + * Defaults to `false` + */ + allowBooleanAttributes?: boolean; + + /** + * Whether to parse tag value with `strnum` package + * + * Defaults to `true` + */ + parseTagValue?: boolean; + + /** + * Whether to parse tag value with `strnum` package + * + * Defaults to `false` + */ + parseAttributeValue?: boolean; + + /** + * Whether to remove surrounding whitespace from tag or attribute value + * + * Defaults to `true` + */ + trimValues?: boolean; + + /** + * Give a property name to set CDATA values to instead of merging to tag's text value + * + * Defaults to `false` + */ + cdataPropName?: false | string; + + /** + * If set, parse comments and set as this property + * + * Defaults to `false` + */ + commentPropName?: false | string; + + /** + * Control how tag value should be parsed. Called only if tag value is not empty + * + * @returns {undefined|null} `undefined` or `null` to set original value. + * @returns {unknown} + * + * 1. Different value or value with different data type to set new value. + * 2. Same value to set parsed value if `parseTagValue: true`. + * + * Defaults to `(tagName, val, jPath, hasAttributes, isLeafNode) => val` + */ + tagValueProcessor?: (tagName: string, tagValue: string, jPath: string, hasAttributes: boolean, isLeafNode: boolean) => unknown; + + /** + * Control how attribute value should be parsed + * + * @param attrName + * @param attrValue + * @param jPath + * @returns {undefined|null} `undefined` or `null` to set original value + * @returns {unknown} + * + * Defaults to `(attrName, val, jPath) => val` + */ + attributeValueProcessor?: (attrName: string, attrValue: string, jPath: string) => unknown; + + /** + * Options to pass to `strnum` for parsing numbers + * + * Defaults to `{ hex: true, leadingZeros: true, eNotation: true }` + */ + numberParseOptions?: strnumOptions; + + /** + * Nodes to stop parsing at + * + * Defaults to `[]` + */ + stopNodes?: string[]; + + /** + * List of tags without closing tags + * + * Defaults to `[]` + */ + unpairedTags?: string[]; + + /** + * Whether to always create a text node + * + * Defaults to `false` + */ + alwaysCreateTextNode?: boolean; + + /** + * Determine whether a tag should be parsed as an array + * + * @param tagName + * @param jPath + * @param isLeafNode + * @param isAttribute + * @returns {boolean} + * + * Defaults to `() => false` + */ + isArray?: (tagName: string, jPath: string, isLeafNode: boolean, isAttribute: boolean) => boolean; + + /** + * Whether to process default and DOCTYPE entities + * + * Defaults to `true` + */ + processEntities?: boolean; + + /** + * Whether to process HTML entities + * + * Defaults to `false` + */ + htmlEntities?: boolean; + + /** + * Whether to ignore the declaration tag from output + * + * Defaults to `false` + */ + ignoreDeclaration?: boolean; + + /** + * Whether to ignore Pi tags + * + * Defaults to `false` + */ + ignorePiTags?: boolean; + + /** + * Transform tag names + * + * Defaults to `false` + */ + transformTagName?: ((tagName: string) => string) | false; + + /** + * Transform attribute names + * + * Defaults to `false` + */ + transformAttributeName?: ((attributeName: string) => string) | false; + + /** + * Change the tag name when a different name is returned. Skip the tag from parsed result when false is returned. + * Modify `attrs` object to control attributes for the given tag. + * + * @returns {string} new tag name. + * @returns false to skip the tag + * + * Defaults to `(tagName, jPath, attrs) => tagName` + */ + updateTag?: (tagName: string, jPath: string, attrs: {[k: string]: string}) => string | boolean; +}; + +type strnumOptions = { + hex: boolean; + leadingZeros: boolean, + skipLike?: RegExp, + eNotation?: boolean +} + +type validationOptions = { + /** + * Whether to allow attributes without value + * + * Defaults to `false` + */ + allowBooleanAttributes?: boolean; + + /** + * List of tags without closing tags + * + * Defaults to `[]` + */ + unpairedTags?: string[]; +}; + +type XmlBuilderOptions = { + /** + * Give a prefix to the attribute name in the resulting JS object + * + * Defaults to '@_' + */ + attributeNamePrefix?: string; + + /** + * A name to group all attributes of a tag under, or `false` to disable + * + * Defaults to `false` + */ + attributesGroupName?: false | string; + + /** + * The name of the next node in the resulting JS + * + * Defaults to `#text` + */ + textNodeName?: string; + + /** + * Whether to ignore attributes when building + * + * When `true` - ignores all the attributes + * + * When `false` - builds all the attributes + * + * When `Array` - filters out attributes that match provided patterns + * + * When `Function` - calls the function for each attribute and filters out those for which the function returned `true` + * + * Defaults to `true` + */ + ignoreAttributes?: boolean | (string | RegExp)[] | ((attrName: string, jPath: string) => boolean); + + /** + * Give a property name to set CDATA values to instead of merging to tag's text value + * + * Defaults to `false` + */ + cdataPropName?: false | string; + + /** + * If set, parse comments and set as this property + * + * Defaults to `false` + */ + commentPropName?: false | string; + + /** + * Whether to make output pretty instead of single line + * + * Defaults to `false` + */ + format?: boolean; + + + /** + * If `format` is set to `true`, sets the indent string + * + * Defaults to ` ` + */ + indentBy?: string; + + /** + * Give a name to a top-level array + * + * Defaults to `undefined` + */ + arrayNodeName?: string; + + /** + * Create empty tags for tags with no text value + * + * Defaults to `false` + */ + suppressEmptyNode?: boolean; + + /** + * Suppress an unpaired tag + * + * Defaults to `true` + */ + suppressUnpairedNode?: boolean; + + /** + * Don't put a value for boolean attributes + * + * Defaults to `true` + */ + suppressBooleanAttributes?: boolean; + + /** + * Preserve the order of tags in resulting JS object + * + * Defaults to `false` + */ + preserveOrder?: boolean; + + /** + * List of tags without closing tags + * + * Defaults to `[]` + */ + unpairedTags?: string[]; + + /** + * Nodes to stop parsing at + * + * Defaults to `[]` + */ + stopNodes?: string[]; + + /** + * Control how tag value should be parsed. Called only if tag value is not empty + * + * @returns {undefined|null} `undefined` or `null` to set original value. + * @returns {unknown} + * + * 1. Different value or value with different data type to set new value. + * 2. Same value to set parsed value if `parseTagValue: true`. + * + * Defaults to `(tagName, val, jPath, hasAttributes, isLeafNode) => val` + */ + tagValueProcessor?: (name: string, value: unknown) => unknown; + + /** + * Control how attribute value should be parsed + * + * @param attrName + * @param attrValue + * @param jPath + * @returns {undefined|null} `undefined` or `null` to set original value + * @returns {unknown} + * + * Defaults to `(attrName, val, jPath) => val` + */ + attributeValueProcessor?: (name: string, value: unknown) => unknown; + + /** + * Whether to process default and DOCTYPE entities + * + * Defaults to `true` + */ + processEntities?: boolean; + + + oneListGroup?: boolean; +}; + +type ESchema = string | object | Array; + +type ValidationError = { + err: { + code: string; + msg: string, + line: number, + col: number + }; +}; + +export class XMLParser { + constructor(options?: X2jOptions); + parse(xmlData: string | Buffer ,validationOptions?: validationOptions | boolean): any; + /** + * Add Entity which is not by default supported by this library + * @param entityIdentifier {string} Eg: 'ent' for &ent; + * @param entityValue {string} Eg: '\r' + */ + addEntity(entityIdentifier: string, entityValue: string): void; +} + +export class XMLValidator{ + static validate( xmlData: string, options?: validationOptions): true | ValidationError; +} +export class XMLBuilder { + constructor(options?: XmlBuilderOptions); + build(jObj: any): any; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/fxp.js b/tools/join-backups/node_modules/fast-xml-parser/src/fxp.js new file mode 100644 index 0000000..9cfa0ac --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/fxp.js @@ -0,0 +1,11 @@ +'use strict'; + +const validator = require('./validator'); +const XMLParser = require('./xmlparser/XMLParser'); +const XMLBuilder = require('./xmlbuilder/json2xml'); + +module.exports = { + XMLParser: XMLParser, + XMLValidator: validator, + XMLBuilder: XMLBuilder +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/ignoreAttributes.js b/tools/join-backups/node_modules/fast-xml-parser/src/ignoreAttributes.js new file mode 100644 index 0000000..9fb346b --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/ignoreAttributes.js @@ -0,0 +1,20 @@ +function getIgnoreAttributesFn(ignoreAttributes) { + if (typeof ignoreAttributes === 'function') { + return ignoreAttributes + } + if (Array.isArray(ignoreAttributes)) { + return (attrName) => { + for (const pattern of ignoreAttributes) { + if (typeof pattern === 'string' && attrName === pattern) { + return true + } + if (pattern instanceof RegExp && pattern.test(attrName)) { + return true + } + } + } + } + return () => false +} + +module.exports = getIgnoreAttributesFn \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/util.js b/tools/join-backups/node_modules/fast-xml-parser/src/util.js new file mode 100644 index 0000000..df0a60d --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/util.js @@ -0,0 +1,72 @@ +'use strict'; + +const nameStartChar = ':A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD'; +const nameChar = nameStartChar + '\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040'; +const nameRegexp = '[' + nameStartChar + '][' + nameChar + ']*' +const regexName = new RegExp('^' + nameRegexp + '$'); + +const getAllMatches = function(string, regex) { + const matches = []; + let match = regex.exec(string); + while (match) { + const allmatches = []; + allmatches.startIndex = regex.lastIndex - match[0].length; + const len = match.length; + for (let index = 0; index < len; index++) { + allmatches.push(match[index]); + } + matches.push(allmatches); + match = regex.exec(string); + } + return matches; +}; + +const isName = function(string) { + const match = regexName.exec(string); + return !(match === null || typeof match === 'undefined'); +}; + +exports.isExist = function(v) { + return typeof v !== 'undefined'; +}; + +exports.isEmptyObject = function(obj) { + return Object.keys(obj).length === 0; +}; + +/** + * Copy all the properties of a into b. + * @param {*} target + * @param {*} a + */ +exports.merge = function(target, a, arrayMode) { + if (a) { + const keys = Object.keys(a); // will return an array of own properties + const len = keys.length; //don't make it inline + for (let i = 0; i < len; i++) { + if (arrayMode === 'strict') { + target[keys[i]] = [ a[keys[i]] ]; + } else { + target[keys[i]] = a[keys[i]]; + } + } + } +}; +/* exports.merge =function (b,a){ + return Object.assign(b,a); +} */ + +exports.getValue = function(v) { + if (exports.isExist(v)) { + return v; + } else { + return ''; + } +}; + +// const fakeCall = function(a) {return a;}; +// const fakeCallNoReturn = function() {}; + +exports.isName = isName; +exports.getAllMatches = getAllMatches; +exports.nameRegexp = nameRegexp; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/CharsSymbol.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/CharsSymbol.js new file mode 100644 index 0000000..fa5ce9e --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/CharsSymbol.js @@ -0,0 +1,16 @@ +modules.export = { + "<" : "<", //tag start + ">" : ">", //tag end + "/" : "/", //close tag + "!" : "!", //comment or docttype + "!--" : "!--", //comment + "-->" : "-->", //comment end + "?" : "?", //pi + "?>" : "?>", //pi end + "?xml" : "?xml", //pi end + "![" : "![", //cdata + "]]>" : "]]>", //cdata end + "[" : "[", + "-" : "-", + "D" : "D", +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/EntitiesParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/EntitiesParser.js new file mode 100644 index 0000000..62cc02f --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/EntitiesParser.js @@ -0,0 +1,107 @@ +const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"}; +const htmlEntities = { + "space": { regex: /&(nbsp|#160);/g, val: " " }, + // "lt" : { regex: /&(lt|#60);/g, val: "<" }, + // "gt" : { regex: /&(gt|#62);/g, val: ">" }, + // "amp" : { regex: /&(amp|#38);/g, val: "&" }, + // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, + // "apos" : { regex: /&(apos|#39);/g, val: "'" }, + "cent" : { regex: /&(cent|#162);/g, val: "¢" }, + "pound" : { regex: /&(pound|#163);/g, val: "£" }, + "yen" : { regex: /&(yen|#165);/g, val: "¥" }, + "euro" : { regex: /&(euro|#8364);/g, val: "€" }, + "copyright" : { regex: /&(copy|#169);/g, val: "©" }, + "reg" : { regex: /&(reg|#174);/g, val: "®" }, + "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, +}; + +class EntitiesParser{ + constructor(replaceHtmlEntities) { + this.replaceHtmlEntities = replaceHtmlEntities; + this.docTypeEntities = {}; + this.lastEntities = { + "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"}, + "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"}, + "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"}, + "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""}, + }; + } + + addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.addExternalEntity(ent,externalEntities[ent]) + } + } + addExternalEntity(key,val){ + validateEntityName(key); + if(val.indexOf("&") !== -1) { + reportWarning(`Entity ${key} is not added as '&' is found in value;`) + return; + }else{ + this.lastEntities[ent] = { + regex: new RegExp("&"+key+";","g"), + val : val + } + } + } + + addDocTypeEntities(entities){ + const entKeys = Object.keys(entities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.docTypeEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : entities[ent] + } + } + } + + parse(val){ + return this.replaceEntitiesValue(val) + } + + /** + * 1. Replace DOCTYPE entities + * 2. Replace external entities + * 3. Replace HTML entities if asked + * @param {string} val + */ + replaceEntitiesValue(val){ + if(typeof val === "string" && val.length > 0){ + for(let entityName in this.docTypeEntities){ + const entity = this.docTypeEntities[entityName]; + val = val.replace( entity.regx, entity.val); + } + for(let entityName in this.lastEntities){ + const entity = this.lastEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + if(this.replaceHtmlEntities){ + for(let entityName in htmlEntities){ + const entity = htmlEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + } + val = val.replace( ampEntity.regex, ampEntity.val); + } + return val; + } +}; + +//an entity name should not contains special characters that may be used in regex +//Eg !?\\\/[]$%{}^&*()<> +const specialChar = "!?\\\/[]$%{}^&*()<>|+"; + +function validateEntityName(name){ + for (let i = 0; i < specialChar.length; i++) { + const ch = specialChar[i]; + if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`); + } + return name; +} + +module.exports = EntitiesParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js new file mode 100644 index 0000000..be1f1d4 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OptionsBuilder.js @@ -0,0 +1,64 @@ + +const JsObjOutputBuilder = require("./OutputBuilders/JsObjBuilder"); + +const defaultOptions = { + preserveOrder: false, + removeNSPrefix: false, // remove NS from tag name or attribute name if true + //ignoreRootElement : false, + stopNodes: [], //nested tags will not be parsed even for errors + // isArray: () => false, //User will set it + htmlEntities: false, + // skipEmptyListItem: false + tags:{ + unpaired: [], + nameFor:{ + cdata: false, + comment: false, + text: '#text' + }, + separateTextProperty: false, + }, + attributes:{ + ignore: false, + booleanType: true, + entities: true, + }, + + // select: ["img[src]"], + // stop: ["anim", "[ads]"] + only: [], // rest tags will be skipped. It will result in flat array + hierarchy: false, //will be used when a particular tag is set to be parsed. + skip: [], // will be skipped from parse result. on('skip') will be triggered + + select: [], // on('select', tag => tag ) will be called if match + stop: [], //given tagPath will not be parsed. innerXML will be set as string value + OutputBuilder: new JsObjOutputBuilder(), +}; + +const buildOptions = function(options) { + const finalOptions = { ... defaultOptions}; + copyProperties(finalOptions,options) + return finalOptions; +}; + +function copyProperties(target, source) { + for (let key in source) { + if (source.hasOwnProperty(key)) { + if (key === 'OutputBuilder') { + target[key] = source[key]; + }else if (typeof source[key] === 'object' && !Array.isArray(source[key])) { + // Recursively copy nested properties + if (typeof target[key] === 'undefined') { + target[key] = {}; + } + copyProperties(target[key], source[key]); + } else { + // Copy non-nested properties + target[key] = source[key]; + } + } + } +} + +exports.buildOptions = buildOptions; +exports.defaultOptions = defaultOptions; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js new file mode 100644 index 0000000..be2d478 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/BaseOutputBuilder.js @@ -0,0 +1,71 @@ +class BaseOutputBuilder{ + constructor(){ + // this.attributes = {}; + } + + addAttribute(name, value){ + if(this.options.onAttribute){ + //TODO: better to pass tag path + const v = this.options.onAttribute(name, value, this.tagName); + if(v) this.attributes[v.name] = v.value; + }else{ + name = this.options.attributes.prefix + name + this.options.attributes.suffix; + this.attributes[name] = this.parseValue(value, this.options.attributes.valueParsers); + } + } + + /** + * parse value by chain of parsers + * @param {string} val + * @returns {any} parsed value if matching parser found + */ + parseValue = function(val, valParsers){ + for (let i = 0; i < valParsers.length; i++) { + let valParser = valParsers[i]; + if(typeof valParser === "string"){ + valParser = this.registeredParsers[valParser]; + } + if(valParser){ + val = valParser.parse(val); + } + } + return val; + } + + /** + * To add a nested empty tag. + * @param {string} key + * @param {any} val + */ + _addChild(key, val){} + + /** + * skip the comment if property is not set + */ + addComment(text){ + if(this.options.nameFor.comment) + this._addChild(this.options.nameFor.comment, text); + } + + //store CDATA separately if property is set + //otherwise add to tag's value + addCdata(text){ + if (this.options.nameFor.cdata) { + this._addChild(this.options.nameFor.cdata, text); + } else { + this.addRawValue(text || ""); + } + } + + addRawValue = text => this.addValue(text); + + addDeclaration(){ + if(!this.options.declaration){ + }else{ + this.addPi("?xml"); + } + this.attributes = {} + } +} + +module.exports = BaseOutputBuilder; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js new file mode 100644 index 0000000..c63f627 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsArrBuilder.js @@ -0,0 +1,103 @@ +const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder"); + +class OutputBuilder{ + constructor(options){ + this.options = buildOptions(options); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsArrBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +const rootName = '!js_arr'; +const BaseOutputBuilder = require("./BaseOutputBuilder"); + +class JsArrBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, options,registeredParsers) { + super(); + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = options; + this.registeredParsers = registeredParsers; + + this.root = new Node(rootName); + this.currentNode = this.root; + this.attributes = {}; + } + + addTag(tag){ + //when a new tag is added, it should be added as child of current node + //TODO: shift this check to the parser + if(tag.name === "__proto__") tag.name = "#__proto__"; + + this.tagsStack.push(this.currentNode); + this.currentNode = new Node(tag.name, this.attributes); + this.attributes = {}; + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const node = this.currentNode; + this.currentNode = this.tagsStack.pop(); //set parent node in scope + if(this.options.onClose !== undefined){ + //TODO TagPathMatcher + const resultTag = this.options.onClose(node, + new TagPathMatcher(this.tagsStack,node)); + + if(resultTag) return; + } + this.currentNode.child.push(node); //to parent node + } + + //Called by parent class methods + _addChild(key, val){ + // if(key === "__proto__") tagName = "#__proto__"; + this.currentNode.child.push( {[key]: val }); + // this.currentNode.leafType = false; + } + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + this.currentNode.child.push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) }); + } + + addPi(name){ + //TODO: set pi flag + if(!this.options.ignorePiTags){ + const node = new Node(name, this.attributes); + this.currentNode[":@"] = this.attributes; + this.currentNode.child.push(node); + } + this.attributes = {}; + } + getOutput(){ + return this.root.child[0]; + } +} + + + +class Node{ + constructor(tagname, attributes){ + this.tagname = tagname; + this.child = []; //nested tags, text, cdata, comments + if(attributes && Object.keys(attributes).length > 0) + this[":@"] = attributes; + } +} + +module.exports = OutputBuilder; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js new file mode 100644 index 0000000..e0dc1e9 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsMinArrBuilder.js @@ -0,0 +1,102 @@ +const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder"); + +class OutputBuilder{ + constructor(options){ + this.options = buildOptions(options); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsMinArrBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +const BaseOutputBuilder = require("./BaseOutputBuilder"); +const rootName = '^'; + +class JsMinArrBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, options,registeredParsers) { + super(); + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = options; + this.registeredParsers = registeredParsers; + + this.root = {[rootName]: []}; + this.currentNode = this.root; + this.currentNodeTagName = rootName; + this.attributes = {}; + } + + addTag(tag){ + //when a new tag is added, it should be added as child of current node + //TODO: shift this check to the parser + if(tag.name === "__proto__") tag.name = "#__proto__"; + + this.tagsStack.push([this.currentNodeTagName,this.currentNode]); //this.currentNode is parent node here + this.currentNodeTagName = tag.name; + this.currentNode = { [tag.name]:[]} + if(Object.keys(this.attributes).length > 0){ + this.currentNode[":@"] = this.attributes; + this.attributes = {}; + } + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const node = this.currentNode; + const nodeName = this.currentNodeTagName; + const arr = this.tagsStack.pop(); //set parent node in scope + this.currentNodeTagName = arr[0]; + this.currentNode = arr[1]; + + if(this.options.onClose !== undefined){ + //TODO TagPathMatcher + const resultTag = this.options.onClose(node, + new TagPathMatcher(this.tagsStack,node)); + + if(resultTag) return; + } + this.currentNode[this.currentNodeTagName].push(node); //to parent node + } + + //Called by parent class methods + _addChild(key, val){ + // if(key === "__proto__") tagName = "#__proto__"; + this.currentNode.push( {[key]: val }); + // this.currentNode.leafType = false; + } + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + this.currentNode[this.currentNodeTagName].push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) }); + } + + addPi(name){ + if(!this.options.ignorePiTags){ + const node = { [name]:[]} + if(this.attributes){ + node[":@"] = this.attributes; + } + this.currentNode.push(node); + } + this.attributes = {}; + } + getOutput(){ + return this.root[rootName]; + } +} + +module.exports = OutputBuilder; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js new file mode 100644 index 0000000..37036c5 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/JsObjBuilder.js @@ -0,0 +1,156 @@ + + +const {buildOptions,registerCommonValueParsers} = require("./ParserOptionsBuilder"); + +class OutputBuilder{ + constructor(builderOptions){ + this.options = buildOptions(builderOptions); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsObjBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +const BaseOutputBuilder = require("./BaseOutputBuilder"); +const rootName = '^'; + +class JsObjBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, builderOptions,registeredParsers) { + super(); + //hold the raw detail of a tag and sequence with reference to the output + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = builderOptions; + this.registeredParsers = registeredParsers; + + this.root = {}; + this.parent = this.root; + this.tagName = rootName; + this.value = {}; + this.textValue = ""; + this.attributes = {}; + } + + addTag(tag){ + + let value = ""; + if( !isEmpty(this.attributes)){ + value = {}; + if(this.options.attributes.groupBy){ + value[this.options.attributes.groupBy] = this.attributes; + }else{ + value = this.attributes; + } + } + + this.tagsStack.push([this.tagName, this.textValue, this.value]); //parent tag, parent text value, parent tag value (jsobj) + this.tagName = tag.name; + this.value = value; + this.textValue = ""; + this.attributes = {}; + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const tagName = this.tagName; + let value = this.value; + let textValue = this.textValue; + + //update tag text value + if(typeof value !== "object" && !Array.isArray(value)){ + value = this.parseValue(textValue.trim(), this.options.tags.valueParsers); + }else if(textValue.length > 0){ + value[this.options.nameFor.text] = this.parseValue(textValue.trim(), this.options.tags.valueParsers); + } + + + let resultTag= { + tagName: tagName, + value: value + }; + + if(this.options.onTagClose !== undefined){ + //TODO TagPathMatcher + resultTag = this.options.onClose(tagName, value, this.textValue, new TagPathMatcher(this.tagsStack,node)); + + if(!resultTag) return; + } + + //set parent node in scope + let arr = this.tagsStack.pop(); + let parentTag = arr[2]; + parentTag=this._addChildTo(resultTag.tagName, resultTag.value, parentTag); + + this.tagName = arr[0]; + this.textValue = arr[1]; + this.value = parentTag; + } + + _addChild(key, val){ + if(typeof this.value === "string"){ + this.value = { [this.options.nameFor.text] : this.value }; + } + + this._addChildTo(key, val, this.value); + // this.currentNode.leafType = false; + this.attributes = {}; + } + + _addChildTo(key, val, node){ + if(typeof node === 'string') node = {}; + if(!node[key]){ + node[key] = val; + }else{ //Repeated + if(!Array.isArray(node[key])){ //but not stored as array + node[key] = [node[key]]; + } + node[key].push(val); + } + return node; + } + + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + //TODO: use bytes join + if(this.textValue.length > 0) this.textValue += " " + text; + else this.textValue = text; + } + + addPi(name){ + let value = ""; + if( !isEmpty(this.attributes)){ + value = {}; + if(this.options.attributes.groupBy){ + value[this.options.attributes.groupBy] = this.attributes; + }else{ + value = this.attributes; + } + } + this._addChild(name, value); + + } + getOutput(){ + return this.value; + } +} + +function isEmpty(obj) { + return Object.keys(obj).length === 0; +} + +module.exports = OutputBuilder; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js new file mode 100644 index 0000000..c71ea94 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/OutputBuilders/ParserOptionsBuilder.js @@ -0,0 +1,99 @@ +const trimParser = require("../valueParsers/trim") +const booleanParser = require("../valueParsers/booleanParser") +const currencyParser = require("../valueParsers/currency") +const numberParser = require("../valueParsers/number") + +const defaultOptions={ + nameFor:{ + text: "#text", + comment: "", + cdata: "", + }, + // onTagClose: () => {}, + // onAttribute: () => {}, + piTag: false, + declaration: false, //"?xml" + tags: { + valueParsers: [ + // "trim", + // "boolean", + // "number", + // "currency", + // "date", + ] + }, + attributes:{ + prefix: "@_", + suffix: "", + groupBy: "", + + valueParsers: [ + // "trim", + // "boolean", + // "number", + // "currency", + // "date", + ] + }, + dataType:{ + + } +} + +//TODO +const withJoin = ["trim","join", /*"entities",*/"number","boolean","currency"/*, "date"*/] +const withoutJoin = ["trim", /*"entities",*/"number","boolean","currency"/*, "date"*/] + +function buildOptions(options){ + //clone + const finalOptions = { ... defaultOptions}; + + //add config missed in cloning + finalOptions.tags.valueParsers.push(...withJoin) + if(!this.preserveOrder) + finalOptions.tags.valueParsers.push(...withoutJoin); + + //add config missed in cloning + finalOptions.attributes.valueParsers.push(...withJoin) + + //override configuration + copyProperties(finalOptions,options); + return finalOptions; +} + +function copyProperties(target, source) { + for (let key in source) { + if (source.hasOwnProperty(key)) { + if (typeof source[key] === 'object' && !Array.isArray(source[key])) { + // Recursively copy nested properties + if (typeof target[key] === 'undefined') { + target[key] = {}; + } + copyProperties(target[key], source[key]); + } else { + // Copy non-nested properties + target[key] = source[key]; + } + } + } +} + +function registerCommonValueParsers(options){ + return { + "trim": new trimParser(), + // "join": this.entityParser.parse, + "boolean": new booleanParser(), + "number": new numberParser({ + hex: true, + leadingZeros: true, + eNotation: true + }), + "currency": new currencyParser(), + // "date": this.entityParser.parse, + } +} + +module.exports = { + buildOptions : buildOptions, + registerCommonValueParsers: registerCommonValueParsers +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/Report.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/Report.js new file mode 100644 index 0000000..e69de29 diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPath.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPath.js new file mode 100644 index 0000000..d901cc3 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPath.js @@ -0,0 +1,81 @@ +class TagPath{ + constructor(pathStr){ + let text = ""; + let tName = ""; + let pos; + let aName = ""; + let aVal = ""; + this.stack = [] + + for (let i = 0; i < pathStr.length; i++) { + let ch = pathStr[i]; + if(ch === " ") { + if(text.length === 0) continue; + tName = text; text = ""; + }else if(ch === "["){ + if(tName.length === 0){ + tName = text; text = ""; + } + i++; + for (; i < pathStr.length; i++) { + ch = pathStr[i]; + if(ch=== "=") continue; + else if(ch=== "]") {aName = text.trim(); text=""; break; i--;} + else if(ch === "'" || ch === '"'){ + let attrEnd = pathStr.indexOf(ch,i+1); + aVal = pathStr.substring(i+1, attrEnd); + i = attrEnd; + }else{ + text +=ch; + } + } + }else if(ch !== " " && text.length === 0 && tName.length > 0){//reading tagName + //save previous tag + this.stack.push(new TagPathNode(tName,pos,aName,aVal)); + text = ch; tName = ""; aName = ""; aVal = ""; + }else{ + text+=ch; + } + } + + //last tag in the path + if(tName.length >0 || text.length>0){ + this.stack.push(new TagPathNode(text||tName,pos,aName,aVal)); + } + } + + match(tagStack,node){ + if(this.stack[0].name !== "*"){ + if(this.stack.length !== tagStack.length +1) return false; + + //loop through tagPath and tagStack and match + for (let i = 0; i < this.tagStack.length; i++) { + if(!this.stack[i].match(tagStack[i])) return false; + } + } + if(!this.stack[this.stack.length - 1].match(node)) return false; + return true; + } +} + +class TagPathNode{ + constructor(name,position,attrName,attrVal){ + this.name = name; + this.position = position; + this.attrName = attrName, + this.attrVal = attrVal; + } + + match(node){ + let matching = true; + matching = node.name === this.name; + if(this.position) matching = node.position === this.position; + if(this.attrName) matching = node.attrs[this.attrName !== undefined]; + if(this.attrVal) matching = node.attrs[this.attrName !== this.attrVal]; + return matching; + } +} + +// console.log((new TagPath("* b[b]")).stack); +// console.log((new TagPath("a[a] b[b] c")).stack); +// console.log((new TagPath(" b [ b= 'cf sdadwa' ] a ")).stack); \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js new file mode 100644 index 0000000..af23607 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/TagPathMatcher.js @@ -0,0 +1,15 @@ +const TagPath = require("./TagPath"); + +class TagPathMatcher{ + constructor(stack,node){ + this.stack = stack; + this.node= node; + } + + match(path){ + const tagPath = new TagPath(path); + return tagPath.match(this.stack, this.node); + } +} + +module.exports = TagPathMatcher; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/XMLParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XMLParser.js new file mode 100644 index 0000000..6de58ed --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XMLParser.js @@ -0,0 +1,85 @@ +const { buildOptions} = require("./OptionsBuilder"); +const Xml2JsParser = require("./Xml2JsParser"); + +class XMLParser{ + + constructor(options){ + this.externalEntities = {}; + this.options = buildOptions(options); + // console.log(this.options) + } + /** + * Parse XML data string to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parse(xmlData){ + if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){ + return this.parse(xmlData); + }else if( xmlData.toString){ + xmlData = xmlData.toString(); + }else{ + throw new Error("XML data is accepted in String or Bytes[] form.") + } + // if( validationOption){ + // if(validationOption === true) validationOption = {}; //validate with default options + + // const result = validator.validate(xmlData, validationOption); + // if (result !== true) { + // throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` ) + // } + // } + const parser = new Xml2JsParser(this.options); + parser.entityParser.addExternalEntities(this.externalEntities); + return parser.parse(xmlData); + } + /** + * Parse XML data buffer to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parseBytesArr(xmlData){ + if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){ + }else{ + throw new Error("XML data is accepted in Bytes[] form.") + } + const parser = new Xml2JsParser(this.options); + parser.entityParser.addExternalEntities(this.externalEntities); + return parser.parseBytesArr(xmlData); + } + /** + * Parse XML data stream to JS object + * @param {fs.ReadableStream} xmlDataStream + */ + parseStream(xmlDataStream){ + if(!isStream(xmlDataStream)) throw new Error("FXP: Invalid stream input"); + + const orderedObjParser = new Xml2JsParser(this.options); + orderedObjParser.entityParser.addExternalEntities(this.externalEntities); + return orderedObjParser.parseStream(xmlDataStream); + } + + /** + * Add Entity which is not by default supported by this library + * @param {string} key + * @param {string} value + */ + addEntity(key, value){ + if(value.indexOf("&") !== -1){ + throw new Error("Entity value can't have '&'") + }else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){ + throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '") + }else if(value === "&"){ + throw new Error("An entity with value '&' is not permitted"); + }else{ + this.externalEntities[key] = value; + } + } +} + +function isStream(stream){ + if(stream && typeof stream.read === "function" && typeof stream.on === "function" && typeof stream.readableEnded === "boolean") return true; + return false; +} + +module.exports = XMLParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js new file mode 100644 index 0000000..c4baab4 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/Xml2JsParser.js @@ -0,0 +1,237 @@ +const StringSource = require("./inputSource/StringSource"); +const BufferSource = require("./inputSource/BufferSource"); +const {readTagExp,readClosingTagName} = require("./XmlPartReader"); +const {readComment, readCdata,readDocType,readPiTag} = require("./XmlSpecialTagsReader"); +const TagPath = require("./TagPath"); +const TagPathMatcher = require("./TagPathMatcher"); +const EntitiesParser = require('./EntitiesParser'); + +//To hold the data of current tag +//This is usually used to compare jpath expression against current tag +class TagDetail{ + constructor(name){ + this.name = name; + this.position = 0; + // this.attributes = {}; + } +} + +class Xml2JsParser { + constructor(options) { + this.options = options; + + this.currentTagDetail = null; + this.tagTextData = ""; + this.tagsStack = []; + this.entityParser = new EntitiesParser(options.htmlEntities); + this.stopNodes = []; + for (let i = 0; i < this.options.stopNodes.length; i++) { + this.stopNodes.push(new TagPath(this.options.stopNodes[i])); + } + } + + parse(strData) { + this.source = new StringSource(strData); + this.parseXml(); + return this.outputBuilder.getOutput(); + } + parseBytesArr(data) { + this.source = new BufferSource(data ); + this.parseXml(); + return this.outputBuilder.getOutput(); + } + + parseXml() { + //TODO: Separate TagValueParser as separate class. So no scope issue in node builder class + + //OutputBuilder should be set in XML Parser + this.outputBuilder = this.options.OutputBuilder.getInstance(this.options); + this.root = { root: true}; + this.currentTagDetail = this.root; + + while(this.source.canRead()){ + let ch = this.source.readCh(); + if (ch === "") break; + + if(ch === "<"){//tagStart + let nextChar = this.source.readChAt(0); + if (nextChar === "" ) throw new Error("Unexpected end of source"); + + + if(nextChar === "!" || nextChar === "?"){ + this.source.updateBufferBoundary(); + //previously collected text should be added to current node + this.addTextNode(); + + this.readSpecialTag(nextChar);// Read DOCTYPE, comment, CDATA, PI tag + }else if(nextChar === "/"){ + this.source.updateBufferBoundary(); + this.readClosingTag(); + // console.log(this.source.buffer.length, this.source.readable); + // console.log(this.tagsStack.length); + }else{//opening tag + this.readOpeningTag(); + } + }else{ + this.tagTextData += ch; + } + }//End While loop + if(this.tagsStack.length > 0 || ( this.tagTextData !== "undefined" && this.tagTextData.trimEnd().length > 0) ) throw new Error("Unexpected data in the end of document"); + } + + /** + * read closing paired tag. Set parent tag in scope. + * skip a node on user's choice + */ + readClosingTag(){ + const tagName = this.processTagName(readClosingTagName(this.source)); + // console.log(tagName, this.tagsStack.length); + this.validateClosingTag(tagName); + // All the text data collected, belongs to current tag. + if(!this.currentTagDetail.root) this.addTextNode(); + this.outputBuilder.closeTag(); + // Since the tag is closed now, parent tag comes in scope + this.currentTagDetail = this.tagsStack.pop(); + } + + validateClosingTag(tagName){ + // This can't be unpaired tag, or a stop tag. + if(this.isUnpaired(tagName) || this.isStopNode(tagName)) throw new Error(`Unexpected closing tag '${tagName}'`); + // This must match with last opening tag + else if(tagName !== this.currentTagDetail.name) + throw new Error(`Unexpected closing tag '${tagName}' expecting '${this.currentTagDetail.name}'`) + } + + /** + * Read paired, unpaired, self-closing, stop and special tags. + * Create a new node + * Push paired tag in stack. + */ + readOpeningTag(){ + //save previously collected text data to current node + this.addTextNode(); + + //create new tag + let tagExp = readTagExp(this, ">" ); + + // process and skip from tagsStack For unpaired tag, self closing tag, and stop node + const tagDetail = new TagDetail(tagExp.tagName); + if(this.isUnpaired(tagExp.tagName)) { + //TODO: this will lead 2 extra stack operation + this.outputBuilder.addTag(tagDetail); + this.outputBuilder.closeTag(); + } else if(tagExp.selfClosing){ + this.outputBuilder.addTag(tagDetail); + this.outputBuilder.closeTag(); + } else if(this.isStopNode(this.currentTagDetail)){ + // TODO: let's user set a stop node boundary detector for complex contents like script tag + //TODO: pass tag name only to avoid string operations + const content = source.readUptoCloseTag(` 0){ + //TODO: shift parsing to output builder + + this.outputBuilder.addValue(this.replaceEntities(this.tagTextData)); + } + this.tagTextData = ""; + } + // } + } + + processAttrName(name){ + if(name === "__proto__") name = "#__proto__"; + name = resolveNameSpace(name, this.removeNSPrefix); + return name; + } + + processTagName(name){ + if(name === "__proto__") name = "#__proto__"; + name = resolveNameSpace(name, this.removeNSPrefix); + return name; + } + + /** + * Generate tags path from tagsStack + */ + tagsPath(tagName){ + //TODO: return TagPath Object. User can call match method with path + return ""; + } + + isUnpaired(tagName){ + return this.options.tags.unpaired.indexOf(tagName) !== -1; + } + + /** + * valid expressions are + * tag nested + * * nested + * tag nested[attribute] + * tag nested[attribute=""] + * tag nested[attribute!=""] + * tag nested:0 //for future + * @param {string} tagName + * @returns + */ + isStopNode(node){ + for (let i = 0; i < this.stopNodes.length; i++) { + const givenPath = this.stopNodes[i]; + if(givenPath.match(this.tagsStack, node)) return true; + } + return false + } + + replaceEntities(text){ + //TODO: if option is set then replace entities + return this.entityParser.parse(text) + } +} + +function resolveNameSpace(name, removeNSPrefix) { + if (removeNSPrefix) { + const parts = name.split(':'); + if(parts.length === 2){ + if (parts[0] === 'xmlns') return ''; + else return parts[1]; + }else reportError(`Multiple namespaces ${name}`) + } + return name; +} + +module.exports = Xml2JsParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlPartReader.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlPartReader.js new file mode 100644 index 0000000..b77fb68 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlPartReader.js @@ -0,0 +1,216 @@ +'use strict'; + +/** + * find paired tag for a stop node + * @param {string} xmlDoc + * @param {string} tagName + * @param {number} i : start index + */ +function readStopNode(xmlDoc, tagName, i){ + const startIndex = i; + // Starting at 1 since we already have an open tag + let openTagCount = 1; + + for (; i < xmlDoc.length; i++) { + if( xmlDoc[i] === "<"){ + if (xmlDoc[i+1] === "/") {//close tag + const closeIndex = findSubStrIndex(xmlDoc, ">", i, `${tagName} is not closed`); + let closeTagName = xmlDoc.substring(i+2,closeIndex).trim(); + if(closeTagName === tagName){ + openTagCount--; + if (openTagCount === 0) { + return { + tagContent: xmlDoc.substring(startIndex, i), + i : closeIndex + } + } + } + i=closeIndex; + } else if(xmlDoc[i+1] === '?') { + const closeIndex = findSubStrIndex(xmlDoc, "?>", i+1, "StopNode is not closed.") + i=closeIndex; + } else if(xmlDoc.substr(i + 1, 3) === '!--') { + const closeIndex = findSubStrIndex(xmlDoc, "-->", i+3, "StopNode is not closed.") + i=closeIndex; + } else if(xmlDoc.substr(i + 1, 2) === '![') { + const closeIndex = findSubStrIndex(xmlDoc, "]]>", i, "StopNode is not closed.") - 2; + i=closeIndex; + } else { + const tagData = readTagExp(xmlDoc, i, '>') + + if (tagData) { + const openTagName = tagData && tagData.tagName; + if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") { + openTagCount++; + } + i=tagData.closeIndex; + } + } + } + }//end for loop +} + +/** + * Read closing tag name + * @param {Source} source + * @returns tag name + */ +function readClosingTagName(source){ + let text = ""; //temporary data + while(source.canRead()){ + let ch = source.readCh(); + // if (ch === null || ch === undefined) break; + // source.updateBuffer(); + + if (ch === ">") return text.trimEnd(); + else text += ch; + } + throw new Error(`Unexpected end of source. Reading '${substr}'`); +} + +/** + * Read XML tag and build attributes map + * This function can be used to read normal tag, pi tag. + * This function can't be used to read comment, CDATA, DOCTYPE. + * Eg + * @param {string} xmlDoc + * @param {number} startIndex starting index + * @returns tag expression includes tag name & attribute string + */ +function readTagExp(parser) { + let inSingleQuotes = false; + let inDoubleQuotes = false; + let i; + let EOE = false; + + for (i = 0; parser.source.canRead(i); i++) { + const char = parser.source.readChAt(i); + + if (char === "'" && !inDoubleQuotes) { + inSingleQuotes = !inSingleQuotes; + } else if (char === '"' && !inSingleQuotes) { + inDoubleQuotes = !inDoubleQuotes; + } else if (char === '>' && !inSingleQuotes && !inDoubleQuotes) { + // If not inside quotes, stop reading at '>' + EOE = true; + break; + } + + } + if(inSingleQuotes || inDoubleQuotes){ + throw new Error("Invalid attribute expression. Quote is not properly closed"); + }else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '>'"); + + + const exp = parser.source.readStr(i); + parser.source.updateBufferBoundary(i + 1); + return buildTagExpObj(exp, parser) +} + +function readPiExp(parser) { + let inSingleQuotes = false; + let inDoubleQuotes = false; + let i; + let EOE = false; + + for (i = 0; parser.source.canRead(i) ; i++) { + const currentChar = parser.source.readChAt(i); + const nextChar = parser.source.readChAt(i+1); + + if (currentChar === "'" && !inDoubleQuotes) { + inSingleQuotes = !inSingleQuotes; + } else if (currentChar === '"' && !inSingleQuotes) { + inDoubleQuotes = !inDoubleQuotes; + } + + if (!inSingleQuotes && !inDoubleQuotes) { + if (currentChar === '?' && nextChar === '>') { + EOE = true; + break; // Exit the loop when '?>' is found + } + } + } + if(inSingleQuotes || inDoubleQuotes){ + throw new Error("Invalid attribute expression. Quote is not properly closed in PI tag expression"); + }else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '?>'"); + + if(!parser.options.attributes.ignore){ + //TODO: use regex to verify attributes if not set to ignore + } + + const exp = parser.source.readStr(i); + parser.source.updateBufferBoundary(i + 1); + return buildTagExpObj(exp, parser) +} + +function buildTagExpObj(exp, parser){ + const tagExp = { + tagName: "", + selfClosing: false + }; + let attrsExp = ""; + + // Check for self-closing tag before setting the name + if(exp[exp.length -1] === "/") { + tagExp.selfClosing = true; + exp = exp.slice(0, -1); // Remove the trailing slash + } + + //separate tag name + let i = 0; + for (; i < exp.length; i++) { + const char = exp[i]; + if(char === " "){ + tagExp.tagName = exp.substring(0, i); + attrsExp = exp.substring(i + 1); + break; + } + } + //only tag + if(tagExp.tagName.length === 0 && i === exp.length)tagExp.tagName = exp; + + tagExp.tagName = tagExp.tagName.trimEnd(); + + if(!parser.options.attributes.ignore && attrsExp.length > 0){ + parseAttributesExp(attrsExp,parser) + } + + return tagExp; +} + +const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm'); + +function parseAttributesExp(attrStr, parser) { + const matches = getAllMatches(attrStr, attrsRegx); + const len = matches.length; //don't make it inline + for (let i = 0; i < len; i++) { + let attrName = parser.processAttrName(matches[i][1]); + let attrVal = parser.replaceEntities(matches[i][4] || true); + + parser.outputBuilder.addAttribute(attrName, attrVal); + } +} + + +const getAllMatches = function(string, regex) { + const matches = []; + let match = regex.exec(string); + while (match) { + const allmatches = []; + allmatches.startIndex = regex.lastIndex - match[0].length; + const len = match.length; + for (let index = 0; index < len; index++) { + allmatches.push(match[index]); + } + matches.push(allmatches); + match = regex.exec(string); + } + return matches; +}; + +module.exports = { + readStopNode: readStopNode, + readClosingTagName: readClosingTagName, + readTagExp: readTagExp, + readPiExp: readPiExp, +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js new file mode 100644 index 0000000..0fba196 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/XmlSpecialTagsReader.js @@ -0,0 +1,118 @@ +const {readPiExp} = require("./XmlPartReader"); + +function readCdata(parser){ + //"); + parser.outputBuilder.addCdata(text); +} +function readPiTag(parser){ + //"); + if(!tagExp) throw new Error("Invalid Pi Tag expression."); + + if (tagExp.tagName === "?xml") {//TODO: test if tagName is just xml + parser.outputBuilder.addDeclaration(); + } else { + parser.outputBuilder.addPi("?"+tagExp.tagName); + } +} + +function readComment(parser){ + //"); + parser.outputBuilder.addComment(text); +} + +const DOCTYPE_tags = { + "EL":/^EMENT\s+([^\s>]+)\s+(ANY|EMPTY|\(.+\)\s*$)/m, + "AT":/^TLIST\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+$/m, + "NO":/^TATION.+$/m +} +function readDocType(parser){ + //"); + const regx = DOCTYPE_tags[str]; + if(regx){ + const match = dTagExp.match(regx); + if(!match) throw new Error("Invalid DOCTYPE"); + }else throw new Error("Invalid DOCTYPE"); + } + }else if( ch === '>' && lastch === "]"){//end of doctype + return; + } + }else if( ch === '>'){//end of doctype + return; + }else if( ch === '['){ + hasBody = true; + }else{ + lastch = ch; + } + }//End While loop + +} + +function registerEntity(parser){ + //read Entity + let attrBoundary=""; + let name ="", val =""; + while(source.canRead()){ + let ch = source.readCh(); + + if(attrBoundary){ + if (ch === attrBoundary){ + val = text; + text = "" + } + }else if(ch === " " || ch === "\t"){ + if(!name){ + name = text.trimStart(); + text = ""; + } + }else if (ch === '"' || ch === "'") {//start of attrBoundary + attrBoundary = ch; + }else if(ch === ">"){ + parser.entityParser.addExternalEntity(name,val); + return; + }else{ + text+=ch; + } + } +} + +module.exports = { + readCdata: readCdata, + readComment:readComment, + readDocType:readDocType, + readPiTag:readPiTag +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js new file mode 100644 index 0000000..b83ce46 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/BufferSource.js @@ -0,0 +1,118 @@ +const Constants = { + space: 32, + tab: 9 +} +class BufferSource{ + constructor(bytesArr){ + this.line = 1; + this.cols = 0; + this.buffer = bytesArr; + this.startIndex = 0; + } + + + + readCh() { + return String.fromCharCode(this.buffer[this.startIndex++]); + } + + readChAt(index) { + return String.fromCharCode(this.buffer[this.startIndex+index]); + } + + readStr(n,from){ + if(typeof from === "undefined") from = this.startIndex; + return this.buffer.slice(from, from + n).toString(); + } + + readUpto(stopStr) { + const inputLength = this.buffer.length; + const stopLength = stopStr.length; + const stopBuffer = Buffer.from(stopStr); + + for (let i = this.startIndex; i < inputLength; i++) { + let match = true; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopBuffer[j]) { + match = false; + break; + } + } + + if (match) { + const result = this.buffer.slice(this.startIndex, i).toString(); + this.startIndex = i + stopLength; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); +} + +readUptoCloseTag(stopStr) { //stopStr: "'){ //TODO: if it should be equivalent ASCII + match = 2; + //tag boundary found + // this.startIndex + } + }else{ + match = 1; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopBuffer[j]) { + match = 0; + break; + } + } + } + if (match === 2) {//matched closing part + const result = this.buffer.slice(this.startIndex, stopIndex - 1 ).toString(); + this.startIndex = i + 1; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); +} + + readFromBuffer(n, shouldUpdate) { + let ch; + if (n === 1) { + ch = this.buffer[this.startIndex]; + if (ch === 10) { + this.line++; + this.cols = 1; + } else { + this.cols++; + } + ch = String.fromCharCode(ch); + } else { + this.cols += n; + ch = this.buffer.slice(this.startIndex, this.startIndex + n).toString(); + } + if (shouldUpdate) this.updateBuffer(n); + return ch; + } + + updateBufferBoundary(n = 1) { //n: number of characters read + this.startIndex += n; + } + + canRead(n){ + n = n || this.startIndex; + return this.buffer.length - n + 1 > 0; + } + +} + +module.exports = BufferSource; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js new file mode 100644 index 0000000..a996528 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/inputSource/StringSource.js @@ -0,0 +1,123 @@ +const whiteSpaces = [" ", "\n", "\t"]; + + +class StringSource{ + constructor(str){ + this.line = 1; + this.cols = 0; + this.buffer = str; + //a boundary pointer to indicate where from the buffer dat should be read + // data before this pointer can be deleted to free the memory + this.startIndex = 0; + } + + readCh() { + return this.buffer[this.startIndex++]; + } + + readChAt(index) { + return this.buffer[this.startIndex+index]; + } + + readStr(n,from){ + if(typeof from === "undefined") from = this.startIndex; + return this.buffer.substring(from, from + n); + } + + readUpto(stopStr) { + const inputLength = this.buffer.length; + const stopLength = stopStr.length; + + for (let i = this.startIndex; i < inputLength; i++) { + let match = true; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopStr[j]) { + match = false; + break; + } + } + + if (match) { + const result = this.buffer.substring(this.startIndex, i); + this.startIndex = i + stopLength; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); + } + + readUptoCloseTag(stopStr) { //stopStr: "'){ + match = 2; + //tag boundary found + // this.startIndex + } + }else{ + match = 1; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopStr[j]) { + match = 0; + break; + } + } + } + if (match === 2) {//matched closing part + const result = this.buffer.substring(this.startIndex, stopIndex - 1 ); + this.startIndex = i + 1; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); + } + + readFromBuffer(n, updateIndex){ + let ch; + if(n===1){ + ch = this.buffer[this.startIndex]; + // if(ch === "\n") { + // this.line++; + // this.cols = 1; + // }else{ + // this.cols++; + // } + }else{ + ch = this.buffer.substring(this.startIndex, this.startIndex + n); + // if("".indexOf("\n") !== -1){ + // //TODO: handle the scenario when there are multiple lines + // //TODO: col should be set to number of chars after last '\n' + // // this.cols = 1; + // }else{ + // this.cols += n; + + // } + } + if(updateIndex) this.updateBufferBoundary(n); + return ch; + } + + //TODO: rename to updateBufferReadIndex + + updateBufferBoundary(n = 1) { //n: number of characters read + this.startIndex += n; + } + + canRead(n){ + n = n || this.startIndex; + return this.buffer.length - n + 1 > 0; + } + +} + +module.exports = StringSource; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js new file mode 100644 index 0000000..62cc02f --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/EntitiesParser.js @@ -0,0 +1,107 @@ +const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"}; +const htmlEntities = { + "space": { regex: /&(nbsp|#160);/g, val: " " }, + // "lt" : { regex: /&(lt|#60);/g, val: "<" }, + // "gt" : { regex: /&(gt|#62);/g, val: ">" }, + // "amp" : { regex: /&(amp|#38);/g, val: "&" }, + // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, + // "apos" : { regex: /&(apos|#39);/g, val: "'" }, + "cent" : { regex: /&(cent|#162);/g, val: "¢" }, + "pound" : { regex: /&(pound|#163);/g, val: "£" }, + "yen" : { regex: /&(yen|#165);/g, val: "¥" }, + "euro" : { regex: /&(euro|#8364);/g, val: "€" }, + "copyright" : { regex: /&(copy|#169);/g, val: "©" }, + "reg" : { regex: /&(reg|#174);/g, val: "®" }, + "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, +}; + +class EntitiesParser{ + constructor(replaceHtmlEntities) { + this.replaceHtmlEntities = replaceHtmlEntities; + this.docTypeEntities = {}; + this.lastEntities = { + "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"}, + "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"}, + "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"}, + "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""}, + }; + } + + addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.addExternalEntity(ent,externalEntities[ent]) + } + } + addExternalEntity(key,val){ + validateEntityName(key); + if(val.indexOf("&") !== -1) { + reportWarning(`Entity ${key} is not added as '&' is found in value;`) + return; + }else{ + this.lastEntities[ent] = { + regex: new RegExp("&"+key+";","g"), + val : val + } + } + } + + addDocTypeEntities(entities){ + const entKeys = Object.keys(entities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.docTypeEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : entities[ent] + } + } + } + + parse(val){ + return this.replaceEntitiesValue(val) + } + + /** + * 1. Replace DOCTYPE entities + * 2. Replace external entities + * 3. Replace HTML entities if asked + * @param {string} val + */ + replaceEntitiesValue(val){ + if(typeof val === "string" && val.length > 0){ + for(let entityName in this.docTypeEntities){ + const entity = this.docTypeEntities[entityName]; + val = val.replace( entity.regx, entity.val); + } + for(let entityName in this.lastEntities){ + const entity = this.lastEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + if(this.replaceHtmlEntities){ + for(let entityName in htmlEntities){ + const entity = htmlEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + } + val = val.replace( ampEntity.regex, ampEntity.val); + } + return val; + } +}; + +//an entity name should not contains special characters that may be used in regex +//Eg !?\\\/[]$%{}^&*()<> +const specialChar = "!?\\\/[]$%{}^&*()<>|+"; + +function validateEntityName(name){ + for (let i = 0; i < specialChar.length; i++) { + const ch = specialChar[i]; + if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`); + } + return name; +} + +module.exports = EntitiesParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js new file mode 100644 index 0000000..f8f5d12 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParser.js @@ -0,0 +1,23 @@ +class boolParser{ + constructor(trueList, falseList){ + if(trueList) + this.trueList = trueList; + else + this.trueList = ["true"]; + + if(falseList) + this.falseList = falseList; + else + this.falseList = ["false"]; + } + parse(val){ + if (typeof val === 'string') { + //TODO: performance: don't convert + const temp = val.toLowerCase(); + if(this.trueList.indexOf(temp) !== -1) return true; + else if(this.falseList.indexOf(temp) !== -1 ) return false; + } + return val; + } +} +module.exports = boolParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js new file mode 100644 index 0000000..21b8050 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/booleanParserExt.js @@ -0,0 +1,20 @@ +function boolParserExt(val){ + if(isArray(val)){ + for (let i = 0; i < val.length; i++) { + val[i] = parse(val[i]) + } + }else{ + val = parse(val) + } + return val; +} + +function parse(val){ + if (typeof val === 'string') { + const temp = val.toLowerCase(); + if(temp === 'true' || temp ==="yes" || temp==="1") return true; + else if(temp === 'false' || temp ==="no" || temp==="0") return false; + } + return val; +} +module.exports = boolParserExt; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js new file mode 100644 index 0000000..82e21e7 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/currency.js @@ -0,0 +1,40 @@ +const defaultOptions = { + maxLength: 200, + // locale: "en-IN" +} +const localeMap = { + "$":"en-US", + "€":"de-DE", + "£":"en-GB", + "¥":"ja-JP", + "₹":"en-IN", +} +const sign = "(?:-|\+)?"; +const digitsAndSeparator = "(?:\d+|\d{1,3}(?:,\d{3})+)"; +const decimalPart = "(?:\.\d{1,2})?"; +const symbol = "(?:\$|€|¥|₹)?"; + +const currencyCheckRegex = /^\s*(?:-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d{1,2})?\s*(?:\$|€|¥|₹)?\s*$/u; + +class CurrencyParser{ + constructor(options){ + this.options = options || defaultOptions; + } + parse(val){ + if (typeof val === 'string' && val.length <= this.options.maxLength) { + if(val.indexOf(",,") !== -1 && val.indexOf(".." !== -1)){ + const match = val.match(currencyCheckRegex); + if(match){ + const locale = this.options.locale || localeMap[match[2]||match[5]||"₹"]; + const formatter = new Intl.NumberFormat(locale) + val = val.replace(/[^0-9,.]/g, '').trim(); + val = Number(val.replace(formatter.format(1000)[1], '')); + } + } + } + return val; + } +} +CurrencyParser.defaultOptions = defaultOptions; + +module.exports = CurrencyParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/join.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/join.js new file mode 100644 index 0000000..d7f2027 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/join.js @@ -0,0 +1,14 @@ +/** + * + * @param {array} val + * @param {string} by + * @returns + */ +function join(val, by=" "){ + if(isArray(val)){ + val.join(by) + } + return val; +} + +module.exports = join; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/number.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/number.js new file mode 100644 index 0000000..bef3803 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/number.js @@ -0,0 +1,16 @@ +const toNumber = require("strnum"); + + +class numParser{ + constructor(options){ + this.options = options; + } + parse(val){ + if (typeof val === 'string') { + val = toNumber(val,this.options); + } + return val; + } +} + +module.exports = numParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js new file mode 100644 index 0000000..ecce49a --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v5/valueParsers/trim.js @@ -0,0 +1,8 @@ +class trimmer{ + parse(val){ + if(typeof val === "string") return val.trim(); + else return val; + } +} + +module.exports = trimmer; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/CharsSymbol.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/CharsSymbol.js new file mode 100644 index 0000000..6ac2de4 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/CharsSymbol.js @@ -0,0 +1,16 @@ +export default { + "<" : "<", //tag start + ">" : ">", //tag end + "/" : "/", //close tag + "!" : "!", //comment or docttype + "!--" : "!--", //comment + "-->" : "-->", //comment end + "?" : "?", //pi + "?>" : "?>", //pi end + "?xml" : "?xml", //pi end + "![" : "![", //cdata + "]]>" : "]]>", //cdata end + "[" : "[", + "-" : "-", + "D" : "D", +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/EntitiesParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/EntitiesParser.js new file mode 100644 index 0000000..0639dd1 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/EntitiesParser.js @@ -0,0 +1,104 @@ +const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"}; +const htmlEntities = { + "space": { regex: /&(nbsp|#160);/g, val: " " }, + // "lt" : { regex: /&(lt|#60);/g, val: "<" }, + // "gt" : { regex: /&(gt|#62);/g, val: ">" }, + // "amp" : { regex: /&(amp|#38);/g, val: "&" }, + // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, + // "apos" : { regex: /&(apos|#39);/g, val: "'" }, + "cent" : { regex: /&(cent|#162);/g, val: "¢" }, + "pound" : { regex: /&(pound|#163);/g, val: "£" }, + "yen" : { regex: /&(yen|#165);/g, val: "¥" }, + "euro" : { regex: /&(euro|#8364);/g, val: "€" }, + "copyright" : { regex: /&(copy|#169);/g, val: "©" }, + "reg" : { regex: /&(reg|#174);/g, val: "®" }, + "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, +}; +export default class EntitiesParser{ + constructor(replaceHtmlEntities) { + this.replaceHtmlEntities = replaceHtmlEntities; + this.docTypeEntities = {}; + this.lastEntities = { + "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"}, + "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"}, + "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"}, + "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""}, + }; + } + + addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.addExternalEntity(ent,externalEntities[ent]) + } + } + addExternalEntity(key,val){ + validateEntityName(key); + if(val.indexOf("&") !== -1) { + reportWarning(`Entity ${key} is not added as '&' is found in value;`) + return; + }else{ + this.lastEntities[ent] = { + regex: new RegExp("&"+key+";","g"), + val : val + } + } + } + + addDocTypeEntities(entities){ + const entKeys = Object.keys(entities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.docTypeEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : entities[ent] + } + } + } + + parse(val){ + return this.replaceEntitiesValue(val) + } + + /** + * 1. Replace DOCTYPE entities + * 2. Replace external entities + * 3. Replace HTML entities if asked + * @param {string} val + */ + replaceEntitiesValue(val){ + if(typeof val === "string" && val.length > 0){ + for(let entityName in this.docTypeEntities){ + const entity = this.docTypeEntities[entityName]; + val = val.replace( entity.regx, entity.val); + } + for(let entityName in this.lastEntities){ + const entity = this.lastEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + if(this.replaceHtmlEntities){ + for(let entityName in htmlEntities){ + const entity = htmlEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + } + val = val.replace( ampEntity.regex, ampEntity.val); + } + return val; + } +}; + +//an entity name should not contains special characters that may be used in regex +//Eg !?\\\/[]$%{}^&*()<> +const specialChar = "!?\\\/[]$%{}^&*()<>|+"; + +function validateEntityName(name){ + for (let i = 0; i < specialChar.length; i++) { + const ch = specialChar[i]; + if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`); + } + return name; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OptionsBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OptionsBuilder.js new file mode 100644 index 0000000..b245166 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OptionsBuilder.js @@ -0,0 +1,61 @@ + +import {JsObjOutputBuilder} from './OutputBuilders/JsObjBuilder.js'; + +export const defaultOptions = { + preserveOrder: false, + removeNSPrefix: false, // remove NS from tag name or attribute name if true + //ignoreRootElement : false, + stopNodes: [], //nested tags will not be parsed even for errors + // isArray: () => false, //User will set it + htmlEntities: false, + // skipEmptyListItem: false + tags:{ + unpaired: [], + nameFor:{ + cdata: false, + comment: false, + text: '#text' + }, + separateTextProperty: false, + }, + attributes:{ + ignore: false, + booleanType: true, + entities: true, + }, + + // select: ["img[src]"], + // stop: ["anim", "[ads]"] + only: [], // rest tags will be skipped. It will result in flat array + hierarchy: false, //will be used when a particular tag is set to be parsed. + skip: [], // will be skipped from parse result. on('skip') will be triggered + + select: [], // on('select', tag => tag ) will be called if match + stop: [], //given tagPath will not be parsed. innerXML will be set as string value + OutputBuilder: new JsObjOutputBuilder(), +}; + +export const buildOptions = function(options) { + const finalOptions = { ... defaultOptions}; + copyProperties(finalOptions,options) + return finalOptions; +}; + +function copyProperties(target, source) { + for (let key in source) { + if (source.hasOwnProperty(key)) { + if (key === 'OutputBuilder') { + target[key] = source[key]; + }else if (typeof source[key] === 'object' && !Array.isArray(source[key])) { + // Recursively copy nested properties + if (typeof target[key] === 'undefined') { + target[key] = {}; + } + copyProperties(target[key], source[key]); + } else { + // Copy non-nested properties + target[key] = source[key]; + } + } + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/BaseOutputBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/BaseOutputBuilder.js new file mode 100644 index 0000000..8f9ce8d --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/BaseOutputBuilder.js @@ -0,0 +1,69 @@ +export default class BaseOutputBuilder{ + constructor(){ + // this.attributes = {}; + } + + addAttribute(name, value){ + if(this.options.onAttribute){ + //TODO: better to pass tag path + const v = this.options.onAttribute(name, value, this.tagName); + if(v) this.attributes[v.name] = v.value; + }else{ + name = this.options.attributes.prefix + name + this.options.attributes.suffix; + this.attributes[name] = this.parseValue(value, this.options.attributes.valueParsers); + } + } + + /** + * parse value by chain of parsers + * @param {string} val + * @returns {any} parsed value if matching parser found + */ + parseValue = function(val, valParsers){ + for (let i = 0; i < valParsers.length; i++) { + let valParser = valParsers[i]; + if(typeof valParser === "string"){ + valParser = this.registeredParsers[valParser]; + } + if(valParser){ + val = valParser.parse(val); + } + } + return val; + } + + /** + * To add a nested empty tag. + * @param {string} key + * @param {any} val + */ + _addChild(key, val){} + + /** + * skip the comment if property is not set + */ + addComment(text){ + if(this.options.nameFor.comment) + this._addChild(this.options.nameFor.comment, text); + } + + //store CDATA separately if property is set + //otherwise add to tag's value + addCdata(text){ + if (this.options.nameFor.cdata) { + this._addChild(this.options.nameFor.cdata, text); + } else { + this.addRawValue(text || ""); + } + } + + addRawValue = text => this.addValue(text); + + addDeclaration(){ + if(!this.options.declaration){ + }else{ + this.addPi("?xml"); + } + this.attributes = {} + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsArrBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsArrBuilder.js new file mode 100644 index 0000000..b9c6e65 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsArrBuilder.js @@ -0,0 +1,103 @@ +import {buildOptions,registerCommonValueParsers} from './ParserOptionsBuilder.js'; + +export default class OutputBuilder{ + constructor(options){ + this.options = buildOptions(options); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsArrBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +const rootName = '!js_arr'; +import BaseOutputBuilder from './BaseOutputBuilder.js'; + +class JsArrBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, options,registeredParsers) { + super(); + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = options; + this.registeredParsers = registeredParsers; + + this.root = new Node(rootName); + this.currentNode = this.root; + this.attributes = {}; + } + + addTag(tag){ + //when a new tag is added, it should be added as child of current node + //TODO: shift this check to the parser + if(tag.name === "__proto__") tag.name = "#__proto__"; + + this.tagsStack.push(this.currentNode); + this.currentNode = new Node(tag.name, this.attributes); + this.attributes = {}; + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const node = this.currentNode; + this.currentNode = this.tagsStack.pop(); //set parent node in scope + if(this.options.onClose !== undefined){ + //TODO TagPathMatcher + const resultTag = this.options.onClose(node, + new TagPathMatcher(this.tagsStack,node)); + + if(resultTag) return; + } + this.currentNode.child.push(node); //to parent node + } + + //Called by parent class methods + _addChild(key, val){ + // if(key === "__proto__") tagName = "#__proto__"; + this.currentNode.child.push( {[key]: val }); + // this.currentNode.leafType = false; + } + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + this.currentNode.child.push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) }); + } + + addPi(name){ + //TODO: set pi flag + if(!this.options.ignorePiTags){ + const node = new Node(name, this.attributes); + this.currentNode[":@"] = this.attributes; + this.currentNode.child.push(node); + } + this.attributes = {}; + } + getOutput(){ + return this.root.child[0]; + } +} + + + +class Node{ + constructor(tagname, attributes){ + this.tagname = tagname; + this.child = []; //nested tags, text, cdata, comments + if(attributes && Object.keys(attributes).length > 0) + this[":@"] = attributes; + } +} + +module.exports = OutputBuilder; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsMinArrBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsMinArrBuilder.js new file mode 100644 index 0000000..be96ebf --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsMinArrBuilder.js @@ -0,0 +1,100 @@ +import {buildOptions,registerCommonValueParsers} from"./ParserOptionsBuilder"; + +export default class OutputBuilder{ + constructor(options){ + this.options = buildOptions(options); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsMinArrBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +import BaseOutputBuilder from "./BaseOutputBuilder.js"; +const rootName = '^'; + +class JsMinArrBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, options,registeredParsers) { + super(); + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = options; + this.registeredParsers = registeredParsers; + + this.root = {[rootName]: []}; + this.currentNode = this.root; + this.currentNodeTagName = rootName; + this.attributes = {}; + } + + addTag(tag){ + //when a new tag is added, it should be added as child of current node + //TODO: shift this check to the parser + if(tag.name === "__proto__") tag.name = "#__proto__"; + + this.tagsStack.push([this.currentNodeTagName,this.currentNode]); //this.currentNode is parent node here + this.currentNodeTagName = tag.name; + this.currentNode = { [tag.name]:[]} + if(Object.keys(this.attributes).length > 0){ + this.currentNode[":@"] = this.attributes; + this.attributes = {}; + } + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const node = this.currentNode; + const nodeName = this.currentNodeTagName; + const arr = this.tagsStack.pop(); //set parent node in scope + this.currentNodeTagName = arr[0]; + this.currentNode = arr[1]; + + if(this.options.onClose !== undefined){ + //TODO TagPathMatcher + const resultTag = this.options.onClose(node, + new TagPathMatcher(this.tagsStack,node)); + + if(resultTag) return; + } + this.currentNode[this.currentNodeTagName].push(node); //to parent node + } + + //Called by parent class methods + _addChild(key, val){ + // if(key === "__proto__") tagName = "#__proto__"; + this.currentNode.push( {[key]: val }); + // this.currentNode.leafType = false; + } + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + this.currentNode[this.currentNodeTagName].push( {[this.options.nameFor.text]: this.parseValue(text, this.options.tags.valueParsers) }); + } + + addPi(name){ + if(!this.options.ignorePiTags){ + const node = { [name]:[]} + if(this.attributes){ + node[":@"] = this.attributes; + } + this.currentNode.push(node); + } + this.attributes = {}; + } + getOutput(){ + return this.root[rootName]; + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsObjBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsObjBuilder.js new file mode 100644 index 0000000..789a42b --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/JsObjBuilder.js @@ -0,0 +1,154 @@ + + +import {buildOptions,registerCommonValueParsers} from './ParserOptionsBuilder.js'; + +export default class OutputBuilder{ + constructor(builderOptions){ + this.options = buildOptions(builderOptions); + this.registeredParsers = registerCommonValueParsers(this.options); + } + + registerValueParser(name,parserInstance){//existing name will override the parser without warning + this.registeredParsers[name] = parserInstance; + } + + getInstance(parserOptions){ + return new JsObjBuilder(parserOptions, this.options, this.registeredParsers); + } +} + +import BaseOutputBuilder from './BaseOutputBuilder.js'; +const rootName = '^'; + +class JsObjBuilder extends BaseOutputBuilder{ + + constructor(parserOptions, builderOptions,registeredParsers) { + super(); + //hold the raw detail of a tag and sequence with reference to the output + this.tagsStack = []; + this.parserOptions = parserOptions; + this.options = builderOptions; + this.registeredParsers = registeredParsers; + + this.root = {}; + this.parent = this.root; + this.tagName = rootName; + this.value = {}; + this.textValue = ""; + this.attributes = {}; + } + + addTag(tag){ + + let value = ""; + if( !isEmpty(this.attributes)){ + value = {}; + if(this.options.attributes.groupBy){ + value[this.options.attributes.groupBy] = this.attributes; + }else{ + value = this.attributes; + } + } + + this.tagsStack.push([this.tagName, this.textValue, this.value]); //parent tag, parent text value, parent tag value (jsobj) + this.tagName = tag.name; + this.value = value; + this.textValue = ""; + this.attributes = {}; + } + + /** + * Check if the node should be added by checking user's preference + * @param {Node} node + * @returns boolean: true if the node should not be added + */ + closeTag(){ + const tagName = this.tagName; + let value = this.value; + let textValue = this.textValue; + + //update tag text value + if(typeof value !== "object" && !Array.isArray(value)){ + value = this.parseValue(textValue.trim(), this.options.tags.valueParsers); + }else if(textValue.length > 0){ + value[this.options.nameFor.text] = this.parseValue(textValue.trim(), this.options.tags.valueParsers); + } + + + let resultTag= { + tagName: tagName, + value: value + }; + + if(this.options.onTagClose !== undefined){ + //TODO TagPathMatcher + resultTag = this.options.onClose(tagName, value, this.textValue, new TagPathMatcher(this.tagsStack,node)); + + if(!resultTag) return; + } + + //set parent node in scope + let arr = this.tagsStack.pop(); + let parentTag = arr[2]; + parentTag=this._addChildTo(resultTag.tagName, resultTag.value, parentTag); + + this.tagName = arr[0]; + this.textValue = arr[1]; + this.value = parentTag; + } + + _addChild(key, val){ + if(typeof this.value === "string"){ + this.value = { [this.options.nameFor.text] : this.value }; + } + + this._addChildTo(key, val, this.value); + // this.currentNode.leafType = false; + this.attributes = {}; + } + + _addChildTo(key, val, node){ + if(typeof node === 'string') node = {}; + if(!node[key]){ + node[key] = val; + }else{ //Repeated + if(!Array.isArray(node[key])){ //but not stored as array + node[key] = [node[key]]; + } + node[key].push(val); + } + return node; + } + + + /** + * Add text value child node + * @param {string} text + */ + addValue(text){ + //TODO: use bytes join + if(this.textValue.length > 0) this.textValue += " " + text; + else this.textValue = text; + } + + addPi(name){ + let value = ""; + if( !isEmpty(this.attributes)){ + value = {}; + if(this.options.attributes.groupBy){ + value[this.options.attributes.groupBy] = this.attributes; + }else{ + value = this.attributes; + } + } + this._addChild(name, value); + + } + getOutput(){ + return this.value; + } +} + +function isEmpty(obj) { + return Object.keys(obj).length === 0; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/ParserOptionsBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/ParserOptionsBuilder.js new file mode 100644 index 0000000..fa0e84e --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/OutputBuilders/ParserOptionsBuilder.js @@ -0,0 +1,94 @@ +import trimParser from "../valueParsers/trim"; +import booleanParser from "../valueParsers/booleanParser"; +import currencyParser from "../valueParsers/currency"; +import numberParser from "../valueParsers/number"; + +const defaultOptions={ + nameFor:{ + text: "#text", + comment: "", + cdata: "", + }, + // onTagClose: () => {}, + // onAttribute: () => {}, + piTag: false, + declaration: false, //"?xml" + tags: { + valueParsers: [ + // "trim", + // "boolean", + // "number", + // "currency", + // "date", + ] + }, + attributes:{ + prefix: "@_", + suffix: "", + groupBy: "", + + valueParsers: [ + // "trim", + // "boolean", + // "number", + // "currency", + // "date", + ] + }, + dataType:{ + + } +} + +//TODO +const withJoin = ["trim","join", /*"entities",*/"number","boolean","currency"/*, "date"*/] +const withoutJoin = ["trim", /*"entities",*/"number","boolean","currency"/*, "date"*/] + +export function buildOptions(options){ + //clone + const finalOptions = { ... defaultOptions}; + + //add config missed in cloning + finalOptions.tags.valueParsers.push(...withJoin) + if(!this.preserveOrder) + finalOptions.tags.valueParsers.push(...withoutJoin); + + //add config missed in cloning + finalOptions.attributes.valueParsers.push(...withJoin) + + //override configuration + copyProperties(finalOptions,options); + return finalOptions; +} + +function copyProperties(target, source) { + for (let key in source) { + if (source.hasOwnProperty(key)) { + if (typeof source[key] === 'object' && !Array.isArray(source[key])) { + // Recursively copy nested properties + if (typeof target[key] === 'undefined') { + target[key] = {}; + } + copyProperties(target[key], source[key]); + } else { + // Copy non-nested properties + target[key] = source[key]; + } + } + } +} + +export function registerCommonValueParsers(options){ + return { + "trim": new trimParser(), + // "join": this.entityParser.parse, + "boolean": new booleanParser(), + "number": new numberParser({ + hex: true, + leadingZeros: true, + eNotation: true + }), + "currency": new currencyParser(), + // "date": this.entityParser.parse, + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/Report.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/Report.js new file mode 100644 index 0000000..e69de29 diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPath.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPath.js new file mode 100644 index 0000000..98148c7 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPath.js @@ -0,0 +1,81 @@ +export default class TagPath{ + constructor(pathStr){ + let text = ""; + let tName = ""; + let pos; + let aName = ""; + let aVal = ""; + this.stack = [] + + for (let i = 0; i < pathStr.length; i++) { + let ch = pathStr[i]; + if(ch === " ") { + if(text.length === 0) continue; + tName = text; text = ""; + }else if(ch === "["){ + if(tName.length === 0){ + tName = text; text = ""; + } + i++; + for (; i < pathStr.length; i++) { + ch = pathStr[i]; + if(ch=== "=") continue; + else if(ch=== "]") {aName = text.trim(); text=""; break; i--;} + else if(ch === "'" || ch === '"'){ + let attrEnd = pathStr.indexOf(ch,i+1); + aVal = pathStr.substring(i+1, attrEnd); + i = attrEnd; + }else{ + text +=ch; + } + } + }else if(ch !== " " && text.length === 0 && tName.length > 0){//reading tagName + //save previous tag + this.stack.push(new TagPathNode(tName,pos,aName,aVal)); + text = ch; tName = ""; aName = ""; aVal = ""; + }else{ + text+=ch; + } + } + + //last tag in the path + if(tName.length >0 || text.length>0){ + this.stack.push(new TagPathNode(text||tName,pos,aName,aVal)); + } + } + + match(tagStack,node){ + if(this.stack[0].name !== "*"){ + if(this.stack.length !== tagStack.length +1) return false; + + //loop through tagPath and tagStack and match + for (let i = 0; i < this.tagStack.length; i++) { + if(!this.stack[i].match(tagStack[i])) return false; + } + } + if(!this.stack[this.stack.length - 1].match(node)) return false; + return true; + } +} + +class TagPathNode{ + constructor(name,position,attrName,attrVal){ + this.name = name; + this.position = position; + this.attrName = attrName, + this.attrVal = attrVal; + } + + match(node){ + let matching = true; + matching = node.name === this.name; + if(this.position) matching = node.position === this.position; + if(this.attrName) matching = node.attrs[this.attrName !== undefined]; + if(this.attrVal) matching = node.attrs[this.attrName !== this.attrVal]; + return matching; + } +} + +// console.log((new TagPath("* b[b]")).stack); +// console.log((new TagPath("a[a] b[b] c")).stack); +// console.log((new TagPath(" b [ b= 'cf sdadwa' ] a ")).stack); \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPathMatcher.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPathMatcher.js new file mode 100644 index 0000000..8110447 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/TagPathMatcher.js @@ -0,0 +1,13 @@ +import {TagPath} from './TagPath.js'; + +export default class TagPathMatcher{ + constructor(stack,node){ + this.stack = stack; + this.node= node; + } + + match(path){ + const tagPath = new TagPath(path); + return tagPath.match(this.stack, this.node); + } +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/XMLParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XMLParser.js new file mode 100644 index 0000000..0da7059 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XMLParser.js @@ -0,0 +1,83 @@ +import { buildOptions} from './OptionsBuilder.js'; +import Xml2JsParser from './Xml2JsParser.js'; + +export default class XMLParser{ + + constructor(options){ + this.externalEntities = {}; + this.options = buildOptions(options); + // console.log(this.options) + } + /** + * Parse XML data string to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parse(xmlData){ + if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){ + return this.parse(xmlData); + }else if( xmlData.toString){ + xmlData = xmlData.toString(); + }else{ + throw new Error("XML data is accepted in String or Bytes[] form.") + } + // if( validationOption){ + // if(validationOption === true) validationOption = {}; //validate with default options + + // const result = validator.validate(xmlData, validationOption); + // if (result !== true) { + // throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` ) + // } + // } + const parser = new Xml2JsParser(this.options); + parser.entityParser.addExternalEntities(this.externalEntities); + return parser.parse(xmlData); + } + /** + * Parse XML data buffer to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parseBytesArr(xmlData){ + if(Array.isArray(xmlData) && xmlData.byteLength !== undefined){ + }else{ + throw new Error("XML data is accepted in Bytes[] form.") + } + const parser = new Xml2JsParser(this.options); + parser.entityParser.addExternalEntities(this.externalEntities); + return parser.parseBytesArr(xmlData); + } + /** + * Parse XML data stream to JS object + * @param {fs.ReadableStream} xmlDataStream + */ + parseStream(xmlDataStream){ + if(!isStream(xmlDataStream)) throw new Error("FXP: Invalid stream input"); + + const orderedObjParser = new Xml2JsParser(this.options); + orderedObjParser.entityParser.addExternalEntities(this.externalEntities); + return orderedObjParser.parseStream(xmlDataStream); + } + + /** + * Add Entity which is not by default supported by this library + * @param {string} key + * @param {string} value + */ + addEntity(key, value){ + if(value.indexOf("&") !== -1){ + throw new Error("Entity value can't have '&'") + }else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){ + throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '") + }else if(value === "&"){ + throw new Error("An entity with value '&' is not permitted"); + }else{ + this.externalEntities[key] = value; + } + } +} + +function isStream(stream){ + if(stream && typeof stream.read === "function" && typeof stream.on === "function" && typeof stream.readableEnded === "boolean") return true; + return false; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/Xml2JsParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/Xml2JsParser.js new file mode 100644 index 0000000..bd62265 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/Xml2JsParser.js @@ -0,0 +1,235 @@ +import StringSource from './inputSource/StringSource.js'; +import BufferSource from './inputSource/BufferSource.js'; +import {readTagExp,readClosingTagName} from './XmlPartReader.js'; +import {readComment, readCdata,readDocType,readPiTag} from './XmlSpecialTagsReader.js'; +import TagPath from './TagPath.js'; +import TagPathMatcher from './TagPathMatcher.js'; +import EntitiesParser from './EntitiesParser.js'; + +//To hold the data of current tag +//This is usually used to compare jpath expression against current tag +class TagDetail{ + constructor(name){ + this.name = name; + this.position = 0; + // this.attributes = {}; + } +} + +export default class Xml2JsParser { + constructor(options) { + this.options = options; + + this.currentTagDetail = null; + this.tagTextData = ""; + this.tagsStack = []; + this.entityParser = new EntitiesParser(options.htmlEntities); + this.stopNodes = []; + for (let i = 0; i < this.options.stopNodes.length; i++) { + this.stopNodes.push(new TagPath(this.options.stopNodes[i])); + } + } + + parse(strData) { + this.source = new StringSource(strData); + this.parseXml(); + return this.outputBuilder.getOutput(); + } + parseBytesArr(data) { + this.source = new BufferSource(data ); + this.parseXml(); + return this.outputBuilder.getOutput(); + } + + parseXml() { + //TODO: Separate TagValueParser as separate class. So no scope issue in node builder class + + //OutputBuilder should be set in XML Parser + this.outputBuilder = this.options.OutputBuilder.getInstance(this.options); + this.root = { root: true}; + this.currentTagDetail = this.root; + + while(this.source.canRead()){ + let ch = this.source.readCh(); + if (ch === "") break; + + if(ch === "<"){//tagStart + let nextChar = this.source.readChAt(0); + if (nextChar === "" ) throw new Error("Unexpected end of source"); + + + if(nextChar === "!" || nextChar === "?"){ + this.source.updateBufferBoundary(); + //previously collected text should be added to current node + this.addTextNode(); + + this.readSpecialTag(nextChar);// Read DOCTYPE, comment, CDATA, PI tag + }else if(nextChar === "/"){ + this.source.updateBufferBoundary(); + this.readClosingTag(); + // console.log(this.source.buffer.length, this.source.readable); + // console.log(this.tagsStack.length); + }else{//opening tag + this.readOpeningTag(); + } + }else{ + this.tagTextData += ch; + } + }//End While loop + if(this.tagsStack.length > 0 || ( this.tagTextData !== "undefined" && this.tagTextData.trimEnd().length > 0) ) throw new Error("Unexpected data in the end of document"); + } + + /** + * read closing paired tag. Set parent tag in scope. + * skip a node on user's choice + */ + readClosingTag(){ + const tagName = this.processTagName(readClosingTagName(this.source)); + // console.log(tagName, this.tagsStack.length); + this.validateClosingTag(tagName); + // All the text data collected, belongs to current tag. + if(!this.currentTagDetail.root) this.addTextNode(); + this.outputBuilder.closeTag(); + // Since the tag is closed now, parent tag comes in scope + this.currentTagDetail = this.tagsStack.pop(); + } + + validateClosingTag(tagName){ + // This can't be unpaired tag, or a stop tag. + if(this.isUnpaired(tagName) || this.isStopNode(tagName)) throw new Error(`Unexpected closing tag '${tagName}'`); + // This must match with last opening tag + else if(tagName !== this.currentTagDetail.name) + throw new Error(`Unexpected closing tag '${tagName}' expecting '${this.currentTagDetail.name}'`) + } + + /** + * Read paired, unpaired, self-closing, stop and special tags. + * Create a new node + * Push paired tag in stack. + */ + readOpeningTag(){ + //save previously collected text data to current node + this.addTextNode(); + + //create new tag + let tagExp = readTagExp(this, ">" ); + + // process and skip from tagsStack For unpaired tag, self closing tag, and stop node + const tagDetail = new TagDetail(tagExp.tagName); + if(this.isUnpaired(tagExp.tagName)) { + //TODO: this will lead 2 extra stack operation + this.outputBuilder.addTag(tagDetail); + this.outputBuilder.closeTag(); + } else if(tagExp.selfClosing){ + this.outputBuilder.addTag(tagDetail); + this.outputBuilder.closeTag(); + } else if(this.isStopNode(this.currentTagDetail)){ + // TODO: let's user set a stop node boundary detector for complex contents like script tag + //TODO: pass tag name only to avoid string operations + const content = source.readUptoCloseTag(` 0){ + //TODO: shift parsing to output builder + + this.outputBuilder.addValue(this.replaceEntities(this.tagTextData)); + } + this.tagTextData = ""; + } + // } + } + + processAttrName(name){ + if(name === "__proto__") name = "#__proto__"; + name = resolveNameSpace(name, this.removeNSPrefix); + return name; + } + + processTagName(name){ + if(name === "__proto__") name = "#__proto__"; + name = resolveNameSpace(name, this.removeNSPrefix); + return name; + } + + /** + * Generate tags path from tagsStack + */ + tagsPath(tagName){ + //TODO: return TagPath Object. User can call match method with path + return ""; + } + + isUnpaired(tagName){ + return this.options.tags.unpaired.indexOf(tagName) !== -1; + } + + /** + * valid expressions are + * tag nested + * * nested + * tag nested[attribute] + * tag nested[attribute=""] + * tag nested[attribute!=""] + * tag nested:0 //for future + * @param {string} tagName + * @returns + */ + isStopNode(node){ + for (let i = 0; i < this.stopNodes.length; i++) { + const givenPath = this.stopNodes[i]; + if(givenPath.match(this.tagsStack, node)) return true; + } + return false + } + + replaceEntities(text){ + //TODO: if option is set then replace entities + return this.entityParser.parse(text) + } +} + +function resolveNameSpace(name, removeNSPrefix) { + if (removeNSPrefix) { + const parts = name.split(':'); + if(parts.length === 2){ + if (parts[0] === 'xmlns') return ''; + else return parts[1]; + }else reportError(`Multiple namespaces ${name}`) + } + return name; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlPartReader.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlPartReader.js new file mode 100644 index 0000000..61c57ec --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlPartReader.js @@ -0,0 +1,210 @@ +'use strict'; + +/** + * find paired tag for a stop node + * @param {string} xmlDoc + * @param {string} tagName + * @param {number} i : start index + */ +export function readStopNode(xmlDoc, tagName, i){ + const startIndex = i; + // Starting at 1 since we already have an open tag + let openTagCount = 1; + + for (; i < xmlDoc.length; i++) { + if( xmlDoc[i] === "<"){ + if (xmlDoc[i+1] === "/") {//close tag + const closeIndex = findSubStrIndex(xmlDoc, ">", i, `${tagName} is not closed`); + let closeTagName = xmlDoc.substring(i+2,closeIndex).trim(); + if(closeTagName === tagName){ + openTagCount--; + if (openTagCount === 0) { + return { + tagContent: xmlDoc.substring(startIndex, i), + i : closeIndex + } + } + } + i=closeIndex; + } else if(xmlDoc[i+1] === '?') { + const closeIndex = findSubStrIndex(xmlDoc, "?>", i+1, "StopNode is not closed.") + i=closeIndex; + } else if(xmlDoc.substr(i + 1, 3) === '!--') { + const closeIndex = findSubStrIndex(xmlDoc, "-->", i+3, "StopNode is not closed.") + i=closeIndex; + } else if(xmlDoc.substr(i + 1, 2) === '![') { + const closeIndex = findSubStrIndex(xmlDoc, "]]>", i, "StopNode is not closed.") - 2; + i=closeIndex; + } else { + const tagData = readTagExp(xmlDoc, i, '>') + + if (tagData) { + const openTagName = tagData && tagData.tagName; + if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") { + openTagCount++; + } + i=tagData.closeIndex; + } + } + } + }//end for loop +} + +/** + * Read closing tag name + * @param {Source} source + * @returns tag name + */ +export function readClosingTagName(source){ + let text = ""; //temporary data + while(source.canRead()){ + let ch = source.readCh(); + // if (ch === null || ch === undefined) break; + // source.updateBuffer(); + + if (ch === ">") return text.trimEnd(); + else text += ch; + } + throw new Error(`Unexpected end of source. Reading '${substr}'`); +} + +/** + * Read XML tag and build attributes map + * This function can be used to read normal tag, pi tag. + * This function can't be used to read comment, CDATA, DOCTYPE. + * Eg + * @param {string} xmlDoc + * @param {number} startIndex starting index + * @returns tag expression includes tag name & attribute string + */ +export function readTagExp(parser) { + let inSingleQuotes = false; + let inDoubleQuotes = false; + let i; + let EOE = false; + + for (i = 0; parser.source.canRead(i); i++) { + const char = parser.source.readChAt(i); + + if (char === "'" && !inDoubleQuotes) { + inSingleQuotes = !inSingleQuotes; + } else if (char === '"' && !inSingleQuotes) { + inDoubleQuotes = !inDoubleQuotes; + } else if (char === '>' && !inSingleQuotes && !inDoubleQuotes) { + // If not inside quotes, stop reading at '>' + EOE = true; + break; + } + + } + if(inSingleQuotes || inDoubleQuotes){ + throw new Error("Invalid attribute expression. Quote is not properly closed"); + }else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '>'"); + + + const exp = parser.source.readStr(i); + parser.source.updateBufferBoundary(i + 1); + return buildTagExpObj(exp, parser) +} + +export function readPiExp(parser) { + let inSingleQuotes = false; + let inDoubleQuotes = false; + let i; + let EOE = false; + + for (i = 0; parser.source.canRead(i) ; i++) { + const currentChar = parser.source.readChAt(i); + const nextChar = parser.source.readChAt(i+1); + + if (currentChar === "'" && !inDoubleQuotes) { + inSingleQuotes = !inSingleQuotes; + } else if (currentChar === '"' && !inSingleQuotes) { + inDoubleQuotes = !inDoubleQuotes; + } + + if (!inSingleQuotes && !inDoubleQuotes) { + if (currentChar === '?' && nextChar === '>') { + EOE = true; + break; // Exit the loop when '?>' is found + } + } + } + if(inSingleQuotes || inDoubleQuotes){ + throw new Error("Invalid attribute expression. Quote is not properly closed in PI tag expression"); + }else if(!EOE) throw new Error("Unexpected closing of source. Waiting for '?>'"); + + if(!parser.options.attributes.ignore){ + //TODO: use regex to verify attributes if not set to ignore + } + + const exp = parser.source.readStr(i); + parser.source.updateBufferBoundary(i + 1); + return buildTagExpObj(exp, parser) +} + +function buildTagExpObj(exp, parser){ + const tagExp = { + tagName: "", + selfClosing: false + }; + let attrsExp = ""; + + // Check for self-closing tag before setting the name + if(exp[exp.length -1] === "/") { + tagExp.selfClosing = true; + exp = exp.slice(0, -1); // Remove the trailing slash + } + + //separate tag name + let i = 0; + for (; i < exp.length; i++) { + const char = exp[i]; + if(char === " "){ + tagExp.tagName = exp.substring(0, i); + attrsExp = exp.substring(i + 1); + break; + } + } + //only tag + if(tagExp.tagName.length === 0 && i === exp.length)tagExp.tagName = exp; + + tagExp.tagName = tagExp.tagName.trimEnd(); + + if(!parser.options.attributes.ignore && attrsExp.length > 0){ + parseAttributesExp(attrsExp,parser) + } + + return tagExp; +} + +const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm'); + +function parseAttributesExp(attrStr, parser) { + const matches = getAllMatches(attrStr, attrsRegx); + const len = matches.length; //don't make it inline + for (let i = 0; i < len; i++) { + let attrName = parser.processAttrName(matches[i][1]); + let attrVal = parser.replaceEntities(matches[i][4] || true); + + parser.outputBuilder.addAttribute(attrName, attrVal); + } +} + + +const getAllMatches = function(string, regex) { + const matches = []; + let match = regex.exec(string); + while (match) { + const allmatches = []; + allmatches.startIndex = regex.lastIndex - match[0].length; + const len = match.length; + for (let index = 0; index < len; index++) { + allmatches.push(match[index]); + } + matches.push(allmatches); + match = regex.exec(string); + } + return matches; +}; + diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlSpecialTagsReader.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlSpecialTagsReader.js new file mode 100644 index 0000000..330e0a4 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/XmlSpecialTagsReader.js @@ -0,0 +1,111 @@ +import {readPiExp} from './XmlPartReader.js'; + +export function readCdata(parser){ + //"); + parser.outputBuilder.addCdata(text); +} +export function readPiTag(parser){ + //"); + if(!tagExp) throw new Error("Invalid Pi Tag expression."); + + if (tagExp.tagName === "?xml") {//TODO: test if tagName is just xml + parser.outputBuilder.addDeclaration(); + } else { + parser.outputBuilder.addPi("?"+tagExp.tagName); + } +} + +export function readComment(parser){ + //"); + parser.outputBuilder.addComment(text); +} + +const DOCTYPE_tags = { + "EL":/^EMENT\s+([^\s>]+)\s+(ANY|EMPTY|\(.+\)\s*$)/m, + "AT":/^TLIST\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+[^\s]+\s+$/m, + "NO":/^TATION.+$/m +} +export function readDocType(parser){ + //"); + const regx = DOCTYPE_tags[str]; + if(regx){ + const match = dTagExp.match(regx); + if(!match) throw new Error("Invalid DOCTYPE"); + }else throw new Error("Invalid DOCTYPE"); + } + }else if( ch === '>' && lastch === "]"){//end of doctype + return; + } + }else if( ch === '>'){//end of doctype + return; + }else if( ch === '['){ + hasBody = true; + }else{ + lastch = ch; + } + }//End While loop + +} + +function registerEntity(parser){ + //read Entity + let attrBoundary=""; + let name ="", val =""; + while(source.canRead()){ + let ch = source.readCh(); + + if(attrBoundary){ + if (ch === attrBoundary){ + val = text; + text = "" + } + }else if(ch === " " || ch === "\t"){ + if(!name){ + name = text.trimStart(); + text = ""; + } + }else if (ch === '"' || ch === "'") {//start of attrBoundary + attrBoundary = ch; + }else if(ch === ">"){ + parser.entityParser.addExternalEntity(name,val); + return; + }else{ + text+=ch; + } + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/BufferSource.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/BufferSource.js new file mode 100644 index 0000000..2c5d8b5 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/BufferSource.js @@ -0,0 +1,116 @@ +const Constants = { + space: 32, + tab: 9 +} +export default class BufferSource{ + constructor(bytesArr){ + this.line = 1; + this.cols = 0; + this.buffer = bytesArr; + this.startIndex = 0; + } + + + + readCh() { + return String.fromCharCode(this.buffer[this.startIndex++]); + } + + readChAt(index) { + return String.fromCharCode(this.buffer[this.startIndex+index]); + } + + readStr(n,from){ + if(typeof from === "undefined") from = this.startIndex; + return this.buffer.slice(from, from + n).toString(); + } + + readUpto(stopStr) { + const inputLength = this.buffer.length; + const stopLength = stopStr.length; + const stopBuffer = Buffer.from(stopStr); + + for (let i = this.startIndex; i < inputLength; i++) { + let match = true; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopBuffer[j]) { + match = false; + break; + } + } + + if (match) { + const result = this.buffer.slice(this.startIndex, i).toString(); + this.startIndex = i + stopLength; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); +} + +readUptoCloseTag(stopStr) { //stopStr: "'){ //TODO: if it should be equivalent ASCII + match = 2; + //tag boundary found + // this.startIndex + } + }else{ + match = 1; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopBuffer[j]) { + match = 0; + break; + } + } + } + if (match === 2) {//matched closing part + const result = this.buffer.slice(this.startIndex, stopIndex - 1 ).toString(); + this.startIndex = i + 1; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); +} + + readFromBuffer(n, shouldUpdate) { + let ch; + if (n === 1) { + ch = this.buffer[this.startIndex]; + if (ch === 10) { + this.line++; + this.cols = 1; + } else { + this.cols++; + } + ch = String.fromCharCode(ch); + } else { + this.cols += n; + ch = this.buffer.slice(this.startIndex, this.startIndex + n).toString(); + } + if (shouldUpdate) this.updateBuffer(n); + return ch; + } + + updateBufferBoundary(n = 1) { //n: number of characters read + this.startIndex += n; + } + + canRead(n){ + n = n || this.startIndex; + return this.buffer.length - n + 1 > 0; + } + +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/StringSource.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/StringSource.js new file mode 100644 index 0000000..275889a --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/inputSource/StringSource.js @@ -0,0 +1,121 @@ +const whiteSpaces = [" ", "\n", "\t"]; + + +export default class StringSource{ + constructor(str){ + this.line = 1; + this.cols = 0; + this.buffer = str; + //a boundary pointer to indicate where from the buffer dat should be read + // data before this pointer can be deleted to free the memory + this.startIndex = 0; + } + + readCh() { + return this.buffer[this.startIndex++]; + } + + readChAt(index) { + return this.buffer[this.startIndex+index]; + } + + readStr(n,from){ + if(typeof from === "undefined") from = this.startIndex; + return this.buffer.substring(from, from + n); + } + + readUpto(stopStr) { + const inputLength = this.buffer.length; + const stopLength = stopStr.length; + + for (let i = this.startIndex; i < inputLength; i++) { + let match = true; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopStr[j]) { + match = false; + break; + } + } + + if (match) { + const result = this.buffer.substring(this.startIndex, i); + this.startIndex = i + stopLength; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); + } + + readUptoCloseTag(stopStr) { //stopStr: "'){ + match = 2; + //tag boundary found + // this.startIndex + } + }else{ + match = 1; + for (let j = 0; j < stopLength; j++) { + if (this.buffer[i + j] !== stopStr[j]) { + match = 0; + break; + } + } + } + if (match === 2) {//matched closing part + const result = this.buffer.substring(this.startIndex, stopIndex - 1 ); + this.startIndex = i + 1; + return result; + } + } + + throw new Error(`Unexpected end of source. Reading '${stopStr}'`); + } + + readFromBuffer(n, updateIndex){ + let ch; + if(n===1){ + ch = this.buffer[this.startIndex]; + // if(ch === "\n") { + // this.line++; + // this.cols = 1; + // }else{ + // this.cols++; + // } + }else{ + ch = this.buffer.substring(this.startIndex, this.startIndex + n); + // if("".indexOf("\n") !== -1){ + // //TODO: handle the scenario when there are multiple lines + // //TODO: col should be set to number of chars after last '\n' + // // this.cols = 1; + // }else{ + // this.cols += n; + + // } + } + if(updateIndex) this.updateBufferBoundary(n); + return ch; + } + + //TODO: rename to updateBufferReadIndex + + updateBufferBoundary(n = 1) { //n: number of characters read + this.startIndex += n; + } + + canRead(n){ + n = n || this.startIndex; + return this.buffer.length - n + 1 > 0; + } + +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/EntitiesParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/EntitiesParser.js new file mode 100644 index 0000000..52b4203 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/EntitiesParser.js @@ -0,0 +1,105 @@ +const ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"}; +const htmlEntities = { + "space": { regex: /&(nbsp|#160);/g, val: " " }, + // "lt" : { regex: /&(lt|#60);/g, val: "<" }, + // "gt" : { regex: /&(gt|#62);/g, val: ">" }, + // "amp" : { regex: /&(amp|#38);/g, val: "&" }, + // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, + // "apos" : { regex: /&(apos|#39);/g, val: "'" }, + "cent" : { regex: /&(cent|#162);/g, val: "¢" }, + "pound" : { regex: /&(pound|#163);/g, val: "£" }, + "yen" : { regex: /&(yen|#165);/g, val: "¥" }, + "euro" : { regex: /&(euro|#8364);/g, val: "€" }, + "copyright" : { regex: /&(copy|#169);/g, val: "©" }, + "reg" : { regex: /&(reg|#174);/g, val: "®" }, + "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, +}; + +export default class EntitiesParser{ + constructor(replaceHtmlEntities) { + this.replaceHtmlEntities = replaceHtmlEntities; + this.docTypeEntities = {}; + this.lastEntities = { + "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"}, + "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"}, + "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"}, + "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""}, + }; + } + + addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.addExternalEntity(ent,externalEntities[ent]) + } + } + addExternalEntity(key,val){ + validateEntityName(key); + if(val.indexOf("&") !== -1) { + reportWarning(`Entity ${key} is not added as '&' is found in value;`) + return; + }else{ + this.lastEntities[ent] = { + regex: new RegExp("&"+key+";","g"), + val : val + } + } + } + + addDocTypeEntities(entities){ + const entKeys = Object.keys(entities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.docTypeEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : entities[ent] + } + } + } + + parse(val){ + return this.replaceEntitiesValue(val) + } + + /** + * 1. Replace DOCTYPE entities + * 2. Replace external entities + * 3. Replace HTML entities if asked + * @param {string} val + */ + replaceEntitiesValue(val){ + if(typeof val === "string" && val.length > 0){ + for(let entityName in this.docTypeEntities){ + const entity = this.docTypeEntities[entityName]; + val = val.replace( entity.regx, entity.val); + } + for(let entityName in this.lastEntities){ + const entity = this.lastEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + if(this.replaceHtmlEntities){ + for(let entityName in htmlEntities){ + const entity = htmlEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + } + val = val.replace( ampEntity.regex, ampEntity.val); + } + return val; + } +}; + +//an entity name should not contains special characters that may be used in regex +//Eg !?\\\/[]$%{}^&*()<> +const specialChar = "!?\\\/[]$%{}^&*()<>|+"; + +function validateEntityName(name){ + for (let i = 0; i < specialChar.length; i++) { + const ch = specialChar[i]; + if(name.indexOf(ch) !== -1) throw new Error(`Invalid character ${ch} in entity name`); + } + return name; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParser.js new file mode 100644 index 0000000..bc8f806 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParser.js @@ -0,0 +1,22 @@ +export default class boolParser{ + constructor(trueList, falseList){ + if(trueList) + this.trueList = trueList; + else + this.trueList = ["true"]; + + if(falseList) + this.falseList = falseList; + else + this.falseList = ["false"]; + } + parse(val){ + if (typeof val === 'string') { + //TODO: performance: don't convert + const temp = val.toLowerCase(); + if(this.trueList.indexOf(temp) !== -1) return true; + else if(this.falseList.indexOf(temp) !== -1 ) return false; + } + return val; + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParserExt.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParserExt.js new file mode 100644 index 0000000..ec3ba42 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/booleanParserExt.js @@ -0,0 +1,19 @@ +export default function boolParserExt(val){ + if(isArray(val)){ + for (let i = 0; i < val.length; i++) { + val[i] = parse(val[i]) + } + }else{ + val = parse(val) + } + return val; +} + +function parse(val){ + if (typeof val === 'string') { + const temp = val.toLowerCase(); + if(temp === 'true' || temp ==="yes" || temp==="1") return true; + else if(temp === 'false' || temp ==="no" || temp==="0") return false; + } + return val; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/currency.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/currency.js new file mode 100644 index 0000000..3772817 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/currency.js @@ -0,0 +1,38 @@ +const defaultOptions = { + maxLength: 200, + // locale: "en-IN" +} +const localeMap = { + "$":"en-US", + "€":"de-DE", + "£":"en-GB", + "¥":"ja-JP", + "₹":"en-IN", +} +const sign = "(?:-|\+)?"; +const digitsAndSeparator = "(?:\d+|\d{1,3}(?:,\d{3})+)"; +const decimalPart = "(?:\.\d{1,2})?"; +const symbol = "(?:\$|€|¥|₹)?"; + +const currencyCheckRegex = /^\s*(?:-|\+)?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d{1,2})?\s*(?:\$|€|¥|₹)?\s*$/u; + +export default class CurrencyParser{ + constructor(options){ + this.options = options || defaultOptions; + } + parse(val){ + if (typeof val === 'string' && val.length <= this.options.maxLength) { + if(val.indexOf(",,") !== -1 && val.indexOf(".." !== -1)){ + const match = val.match(currencyCheckRegex); + if(match){ + const locale = this.options.locale || localeMap[match[2]||match[5]||"₹"]; + const formatter = new Intl.NumberFormat(locale) + val = val.replace(/[^0-9,.]/g, '').trim(); + val = Number(val.replace(formatter.format(1000)[1], '')); + } + } + } + return val; + } +} +CurrencyParser.defaultOptions = defaultOptions; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/join.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/join.js new file mode 100644 index 0000000..f597d99 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/join.js @@ -0,0 +1,13 @@ +/** + * + * @param {array} val + * @param {string} by + * @returns + */ +export default function join(val, by=" "){ + if(isArray(val)){ + val.join(by) + } + return val; +} + diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/number.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/number.js new file mode 100644 index 0000000..8397fb6 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/number.js @@ -0,0 +1,14 @@ +import toNumber from "strnum"; + + +export default class numParser{ + constructor(options){ + this.options = options; + } + parse(val){ + if (typeof val === 'string') { + val = toNumber(val,this.options); + } + return val; + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/trim.js b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/trim.js new file mode 100644 index 0000000..50eed7f --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/v6/valueParsers/trim.js @@ -0,0 +1,6 @@ +export default class trimmer{ + parse(val){ + if(typeof val === "string") return val.trim(); + else return val; + } +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/validator.js b/tools/join-backups/node_modules/fast-xml-parser/src/validator.js new file mode 100644 index 0000000..3b1b2ef --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/validator.js @@ -0,0 +1,425 @@ +'use strict'; + +const util = require('./util'); + +const defaultOptions = { + allowBooleanAttributes: false, //A tag can have attributes without any value + unpairedTags: [] +}; + +//const tagsPattern = new RegExp("<\\/?([\\w:\\-_\.]+)\\s*\/?>","g"); +exports.validate = function (xmlData, options) { + options = Object.assign({}, defaultOptions, options); + + //xmlData = xmlData.replace(/(\r\n|\n|\r)/gm,"");//make it single line + //xmlData = xmlData.replace(/(^\s*<\?xml.*?\?>)/g,"");//Remove XML starting tag + //xmlData = xmlData.replace(/()/g,"");//Remove DOCTYPE + const tags = []; + let tagFound = false; + + //indicates that the root tag has been closed (aka. depth 0 has been reached) + let reachedRoot = false; + + if (xmlData[0] === '\ufeff') { + // check for byte order mark (BOM) + xmlData = xmlData.substr(1); + } + + for (let i = 0; i < xmlData.length; i++) { + + if (xmlData[i] === '<' && xmlData[i+1] === '?') { + i+=2; + i = readPI(xmlData,i); + if (i.err) return i; + }else if (xmlData[i] === '<') { + //starting of tag + //read until you reach to '>' avoiding any '>' in attribute value + let tagStartPos = i; + i++; + + if (xmlData[i] === '!') { + i = readCommentAndCDATA(xmlData, i); + continue; + } else { + let closingTag = false; + if (xmlData[i] === '/') { + //closing tag + closingTag = true; + i++; + } + //read tagname + let tagName = ''; + for (; i < xmlData.length && + xmlData[i] !== '>' && + xmlData[i] !== ' ' && + xmlData[i] !== '\t' && + xmlData[i] !== '\n' && + xmlData[i] !== '\r'; i++ + ) { + tagName += xmlData[i]; + } + tagName = tagName.trim(); + //console.log(tagName); + + if (tagName[tagName.length - 1] === '/') { + //self closing tag without attributes + tagName = tagName.substring(0, tagName.length - 1); + //continue; + i--; + } + if (!validateTagName(tagName)) { + let msg; + if (tagName.trim().length === 0) { + msg = "Invalid space after '<'."; + } else { + msg = "Tag '"+tagName+"' is an invalid name."; + } + return getErrorObject('InvalidTag', msg, getLineNumberForPosition(xmlData, i)); + } + + const result = readAttributeStr(xmlData, i); + if (result === false) { + return getErrorObject('InvalidAttr', "Attributes for '"+tagName+"' have open quote.", getLineNumberForPosition(xmlData, i)); + } + let attrStr = result.value; + i = result.index; + + if (attrStr[attrStr.length - 1] === '/') { + //self closing tag + const attrStrStart = i - attrStr.length; + attrStr = attrStr.substring(0, attrStr.length - 1); + const isValid = validateAttributeString(attrStr, options); + if (isValid === true) { + tagFound = true; + //continue; //text may presents after self closing tag + } else { + //the result from the nested function returns the position of the error within the attribute + //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute + //this gives us the absolute index in the entire xml, which we can use to find the line at last + return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line)); + } + } else if (closingTag) { + if (!result.tagClosed) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' doesn't have proper closing.", getLineNumberForPosition(xmlData, i)); + } else if (attrStr.trim().length > 0) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos)); + } else if (tags.length === 0) { + return getErrorObject('InvalidTag', "Closing tag '"+tagName+"' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos)); + } else { + const otg = tags.pop(); + if (tagName !== otg.tagName) { + let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos); + return getErrorObject('InvalidTag', + "Expected closing tag '"+otg.tagName+"' (opened in line "+openPos.line+", col "+openPos.col+") instead of closing tag '"+tagName+"'.", + getLineNumberForPosition(xmlData, tagStartPos)); + } + + //when there are no more tags, we reached the root level. + if (tags.length == 0) { + reachedRoot = true; + } + } + } else { + const isValid = validateAttributeString(attrStr, options); + if (isValid !== true) { + //the result from the nested function returns the position of the error within the attribute + //in order to get the 'true' error line, we need to calculate the position where the attribute begins (i - attrStr.length) and then add the position within the attribute + //this gives us the absolute index in the entire xml, which we can use to find the line at last + return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line)); + } + + //if the root level has been reached before ... + if (reachedRoot === true) { + return getErrorObject('InvalidXml', 'Multiple possible root nodes found.', getLineNumberForPosition(xmlData, i)); + } else if(options.unpairedTags.indexOf(tagName) !== -1){ + //don't push into stack + } else { + tags.push({tagName, tagStartPos}); + } + tagFound = true; + } + + //skip tag text value + //It may include comments and CDATA value + for (i++; i < xmlData.length; i++) { + if (xmlData[i] === '<') { + if (xmlData[i + 1] === '!') { + //comment or CADATA + i++; + i = readCommentAndCDATA(xmlData, i); + continue; + } else if (xmlData[i+1] === '?') { + i = readPI(xmlData, ++i); + if (i.err) return i; + } else{ + break; + } + } else if (xmlData[i] === '&') { + const afterAmp = validateAmpersand(xmlData, i); + if (afterAmp == -1) + return getErrorObject('InvalidChar', "char '&' is not expected.", getLineNumberForPosition(xmlData, i)); + i = afterAmp; + }else{ + if (reachedRoot === true && !isWhiteSpace(xmlData[i])) { + return getErrorObject('InvalidXml', "Extra text at the end", getLineNumberForPosition(xmlData, i)); + } + } + } //end of reading tag text value + if (xmlData[i] === '<') { + i--; + } + } + } else { + if ( isWhiteSpace(xmlData[i])) { + continue; + } + return getErrorObject('InvalidChar', "char '"+xmlData[i]+"' is not expected.", getLineNumberForPosition(xmlData, i)); + } + } + + if (!tagFound) { + return getErrorObject('InvalidXml', 'Start tag expected.', 1); + }else if (tags.length == 1) { + return getErrorObject('InvalidTag', "Unclosed tag '"+tags[0].tagName+"'.", getLineNumberForPosition(xmlData, tags[0].tagStartPos)); + }else if (tags.length > 0) { + return getErrorObject('InvalidXml', "Invalid '"+ + JSON.stringify(tags.map(t => t.tagName), null, 4).replace(/\r?\n/g, '')+ + "' found.", {line: 1, col: 1}); + } + + return true; +}; + +function isWhiteSpace(char){ + return char === ' ' || char === '\t' || char === '\n' || char === '\r'; +} +/** + * Read Processing insstructions and skip + * @param {*} xmlData + * @param {*} i + */ +function readPI(xmlData, i) { + const start = i; + for (; i < xmlData.length; i++) { + if (xmlData[i] == '?' || xmlData[i] == ' ') { + //tagname + const tagname = xmlData.substr(start, i - start); + if (i > 5 && tagname === 'xml') { + return getErrorObject('InvalidXml', 'XML declaration allowed only at the start of the document.', getLineNumberForPosition(xmlData, i)); + } else if (xmlData[i] == '?' && xmlData[i + 1] == '>') { + //check if valid attribut string + i++; + break; + } else { + continue; + } + } + } + return i; +} + +function readCommentAndCDATA(xmlData, i) { + if (xmlData.length > i + 5 && xmlData[i + 1] === '-' && xmlData[i + 2] === '-') { + //comment + for (i += 3; i < xmlData.length; i++) { + if (xmlData[i] === '-' && xmlData[i + 1] === '-' && xmlData[i + 2] === '>') { + i += 2; + break; + } + } + } else if ( + xmlData.length > i + 8 && + xmlData[i + 1] === 'D' && + xmlData[i + 2] === 'O' && + xmlData[i + 3] === 'C' && + xmlData[i + 4] === 'T' && + xmlData[i + 5] === 'Y' && + xmlData[i + 6] === 'P' && + xmlData[i + 7] === 'E' + ) { + let angleBracketsCount = 1; + for (i += 8; i < xmlData.length; i++) { + if (xmlData[i] === '<') { + angleBracketsCount++; + } else if (xmlData[i] === '>') { + angleBracketsCount--; + if (angleBracketsCount === 0) { + break; + } + } + } + } else if ( + xmlData.length > i + 9 && + xmlData[i + 1] === '[' && + xmlData[i + 2] === 'C' && + xmlData[i + 3] === 'D' && + xmlData[i + 4] === 'A' && + xmlData[i + 5] === 'T' && + xmlData[i + 6] === 'A' && + xmlData[i + 7] === '[' + ) { + for (i += 8; i < xmlData.length; i++) { + if (xmlData[i] === ']' && xmlData[i + 1] === ']' && xmlData[i + 2] === '>') { + i += 2; + break; + } + } + } + + return i; +} + +const doubleQuote = '"'; +const singleQuote = "'"; + +/** + * Keep reading xmlData until '<' is found outside the attribute value. + * @param {string} xmlData + * @param {number} i + */ +function readAttributeStr(xmlData, i) { + let attrStr = ''; + let startChar = ''; + let tagClosed = false; + for (; i < xmlData.length; i++) { + if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) { + if (startChar === '') { + startChar = xmlData[i]; + } else if (startChar !== xmlData[i]) { + //if vaue is enclosed with double quote then single quotes are allowed inside the value and vice versa + } else { + startChar = ''; + } + } else if (xmlData[i] === '>') { + if (startChar === '') { + tagClosed = true; + break; + } + } + attrStr += xmlData[i]; + } + if (startChar !== '') { + return false; + } + + return { + value: attrStr, + index: i, + tagClosed: tagClosed + }; +} + +/** + * Select all the attributes whether valid or invalid. + */ +const validAttrStrRegxp = new RegExp('(\\s*)([^\\s=]+)(\\s*=)?(\\s*([\'"])(([\\s\\S])*?)\\5)?', 'g'); + +//attr, ="sd", a="amit's", a="sd"b="saf", ab cd="" + +function validateAttributeString(attrStr, options) { + //console.log("start:"+attrStr+":end"); + + //if(attrStr.trim().length === 0) return true; //empty string + + const matches = util.getAllMatches(attrStr, validAttrStrRegxp); + const attrNames = {}; + + for (let i = 0; i < matches.length; i++) { + if (matches[i][1].length === 0) { + //nospace before attribute name: a="sd"b="saf" + return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' has no space in starting.", getPositionFromMatch(matches[i])) + } else if (matches[i][3] !== undefined && matches[i][4] === undefined) { + return getErrorObject('InvalidAttr', "Attribute '"+matches[i][2]+"' is without value.", getPositionFromMatch(matches[i])); + } else if (matches[i][3] === undefined && !options.allowBooleanAttributes) { + //independent attribute: ab + return getErrorObject('InvalidAttr', "boolean attribute '"+matches[i][2]+"' is not allowed.", getPositionFromMatch(matches[i])); + } + /* else if(matches[i][6] === undefined){//attribute without value: ab= + return { err: { code:"InvalidAttr",msg:"attribute " + matches[i][2] + " has no value assigned."}}; + } */ + const attrName = matches[i][2]; + if (!validateAttrName(attrName)) { + return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is an invalid name.", getPositionFromMatch(matches[i])); + } + if (!attrNames.hasOwnProperty(attrName)) { + //check for duplicate attribute. + attrNames[attrName] = 1; + } else { + return getErrorObject('InvalidAttr', "Attribute '"+attrName+"' is repeated.", getPositionFromMatch(matches[i])); + } + } + + return true; +} + +function validateNumberAmpersand(xmlData, i) { + let re = /\d/; + if (xmlData[i] === 'x') { + i++; + re = /[\da-fA-F]/; + } + for (; i < xmlData.length; i++) { + if (xmlData[i] === ';') + return i; + if (!xmlData[i].match(re)) + break; + } + return -1; +} + +function validateAmpersand(xmlData, i) { + // https://www.w3.org/TR/xml/#dt-charref + i++; + if (xmlData[i] === ';') + return -1; + if (xmlData[i] === '#') { + i++; + return validateNumberAmpersand(xmlData, i); + } + let count = 0; + for (; i < xmlData.length; i++, count++) { + if (xmlData[i].match(/\w/) && count < 20) + continue; + if (xmlData[i] === ';') + break; + return -1; + } + return i; +} + +function getErrorObject(code, message, lineNumber) { + return { + err: { + code: code, + msg: message, + line: lineNumber.line || lineNumber, + col: lineNumber.col, + }, + }; +} + +function validateAttrName(attrName) { + return util.isName(attrName); +} + +// const startsWithXML = /^xml/i; + +function validateTagName(tagname) { + return util.isName(tagname) /* && !tagname.match(startsWithXML) */; +} + +//this function returns the line number for the character at the given index +function getLineNumberForPosition(xmlData, index) { + const lines = xmlData.substring(0, index).split(/\r?\n/); + return { + line: lines.length, + + // column number is last line's length + 1, because column numbering starts at 1: + col: lines[lines.length - 1].length + 1 + }; +} + +//this function returns the position of the first character of match within attrStr +function getPositionFromMatch(match) { + return match.startIndex + match[1].length; +} diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js new file mode 100644 index 0000000..2274dfa --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlbuilder/json2xml.js @@ -0,0 +1,286 @@ +'use strict'; +//parse Empty Node as self closing node +const buildFromOrderedJs = require('./orderedJs2Xml'); +const getIgnoreAttributesFn = require('../ignoreAttributes') + +const defaultOptions = { + attributeNamePrefix: '@_', + attributesGroupName: false, + textNodeName: '#text', + ignoreAttributes: true, + cdataPropName: false, + format: false, + indentBy: ' ', + suppressEmptyNode: false, + suppressUnpairedNode: true, + suppressBooleanAttributes: true, + tagValueProcessor: function(key, a) { + return a; + }, + attributeValueProcessor: function(attrName, a) { + return a; + }, + preserveOrder: false, + commentPropName: false, + unpairedTags: [], + entities: [ + { regex: new RegExp("&", "g"), val: "&" },//it must be on top + { regex: new RegExp(">", "g"), val: ">" }, + { regex: new RegExp("<", "g"), val: "<" }, + { regex: new RegExp("\'", "g"), val: "'" }, + { regex: new RegExp("\"", "g"), val: """ } + ], + processEntities: true, + stopNodes: [], + // transformTagName: false, + // transformAttributeName: false, + oneListGroup: false +}; + +function Builder(options) { + this.options = Object.assign({}, defaultOptions, options); + if (this.options.ignoreAttributes === true || this.options.attributesGroupName) { + this.isAttribute = function(/*a*/) { + return false; + }; + } else { + this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes) + this.attrPrefixLen = this.options.attributeNamePrefix.length; + this.isAttribute = isAttribute; + } + + this.processTextOrObjNode = processTextOrObjNode + + if (this.options.format) { + this.indentate = indentate; + this.tagEndChar = '>\n'; + this.newLine = '\n'; + } else { + this.indentate = function() { + return ''; + }; + this.tagEndChar = '>'; + this.newLine = ''; + } +} + +Builder.prototype.build = function(jObj) { + if(this.options.preserveOrder){ + return buildFromOrderedJs(jObj, this.options); + }else { + if(Array.isArray(jObj) && this.options.arrayNodeName && this.options.arrayNodeName.length > 1){ + jObj = { + [this.options.arrayNodeName] : jObj + } + } + return this.j2x(jObj, 0, []).val; + } +}; + +Builder.prototype.j2x = function(jObj, level, ajPath) { + let attrStr = ''; + let val = ''; + const jPath = ajPath.join('.') + for (let key in jObj) { + if(!Object.prototype.hasOwnProperty.call(jObj, key)) continue; + if (typeof jObj[key] === 'undefined') { + // supress undefined node only if it is not an attribute + if (this.isAttribute(key)) { + val += ''; + } + } else if (jObj[key] === null) { + // null attribute should be ignored by the attribute list, but should not cause the tag closing + if (this.isAttribute(key)) { + val += ''; + } else if (key === this.options.cdataPropName) { + val += ''; + } else if (key[0] === '?') { + val += this.indentate(level) + '<' + key + '?' + this.tagEndChar; + } else { + val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } + // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } else if (jObj[key] instanceof Date) { + val += this.buildTextValNode(jObj[key], key, '', level); + } else if (typeof jObj[key] !== 'object') { + //premitive type + const attr = this.isAttribute(key); + if (attr && !this.ignoreAttributesFn(attr, jPath)) { + attrStr += this.buildAttrPairStr(attr, '' + jObj[key]); + } else if (!attr) { + //tag value + if (key === this.options.textNodeName) { + let newval = this.options.tagValueProcessor(key, '' + jObj[key]); + val += this.replaceEntitiesValue(newval); + } else { + val += this.buildTextValNode(jObj[key], key, '', level); + } + } + } else if (Array.isArray(jObj[key])) { + //repeated nodes + const arrLen = jObj[key].length; + let listTagVal = ""; + let listTagAttr = ""; + for (let j = 0; j < arrLen; j++) { + const item = jObj[key][j]; + if (typeof item === 'undefined') { + // supress undefined node + } else if (item === null) { + if(key[0] === "?") val += this.indentate(level) + '<' + key + '?' + this.tagEndChar; + else val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + // val += this.indentate(level) + '<' + key + '/' + this.tagEndChar; + } else if (typeof item === 'object') { + if(this.options.oneListGroup){ + const result = this.j2x(item, level + 1, ajPath.concat(key)); + listTagVal += result.val; + if (this.options.attributesGroupName && item.hasOwnProperty(this.options.attributesGroupName)) { + listTagAttr += result.attrStr + } + }else{ + listTagVal += this.processTextOrObjNode(item, key, level, ajPath) + } + } else { + if (this.options.oneListGroup) { + let textValue = this.options.tagValueProcessor(key, item); + textValue = this.replaceEntitiesValue(textValue); + listTagVal += textValue; + } else { + listTagVal += this.buildTextValNode(item, key, '', level); + } + } + } + if(this.options.oneListGroup){ + listTagVal = this.buildObjectNode(listTagVal, key, listTagAttr, level); + } + val += listTagVal; + } else { + //nested node + if (this.options.attributesGroupName && key === this.options.attributesGroupName) { + const Ks = Object.keys(jObj[key]); + const L = Ks.length; + for (let j = 0; j < L; j++) { + attrStr += this.buildAttrPairStr(Ks[j], '' + jObj[key][Ks[j]]); + } + } else { + val += this.processTextOrObjNode(jObj[key], key, level, ajPath) + } + } + } + return {attrStr: attrStr, val: val}; +}; + +Builder.prototype.buildAttrPairStr = function(attrName, val){ + val = this.options.attributeValueProcessor(attrName, '' + val); + val = this.replaceEntitiesValue(val); + if (this.options.suppressBooleanAttributes && val === "true") { + return ' ' + attrName; + } else return ' ' + attrName + '="' + val + '"'; +} + +function processTextOrObjNode (object, key, level, ajPath) { + const result = this.j2x(object, level + 1, ajPath.concat(key)); + if (object[this.options.textNodeName] !== undefined && Object.keys(object).length === 1) { + return this.buildTextValNode(object[this.options.textNodeName], key, result.attrStr, level); + } else { + return this.buildObjectNode(result.val, key, result.attrStr, level); + } +} + +Builder.prototype.buildObjectNode = function(val, key, attrStr, level) { + if(val === ""){ + if(key[0] === "?") return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; + else { + return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar; + } + }else{ + + let tagEndExp = '' + val + tagEndExp ); + } else if (this.options.commentPropName !== false && key === this.options.commentPropName && piClosingChar.length === 0) { + return this.indentate(level) + `` + this.newLine; + }else { + return ( + this.indentate(level) + '<' + key + attrStr + piClosingChar + this.tagEndChar + + val + + this.indentate(level) + tagEndExp ); + } + } +} + +Builder.prototype.closeTag = function(key){ + let closeTag = ""; + if(this.options.unpairedTags.indexOf(key) !== -1){ //unpaired + if(!this.options.suppressUnpairedNode) closeTag = "/" + }else if(this.options.suppressEmptyNode){ //empty + closeTag = "/"; + }else{ + closeTag = `>` + this.newLine; + }else if (this.options.commentPropName !== false && key === this.options.commentPropName) { + return this.indentate(level) + `` + this.newLine; + }else if(key[0] === "?") {//PI tag + return this.indentate(level) + '<' + key + attrStr+ '?' + this.tagEndChar; + }else{ + let textValue = this.options.tagValueProcessor(key, val); + textValue = this.replaceEntitiesValue(textValue); + + if( textValue === ''){ + return this.indentate(level) + '<' + key + attrStr + this.closeTag(key) + this.tagEndChar; + }else{ + return this.indentate(level) + '<' + key + attrStr + '>' + + textValue + + ' 0 && this.options.processEntities){ + for (let i=0; i 0) { + indentation = EOL; + } + return arrToStr(jArray, options, "", indentation); +} + +function arrToStr(arr, options, jPath, indentation) { + let xmlStr = ""; + let isPreviousElementTag = false; + + for (let i = 0; i < arr.length; i++) { + const tagObj = arr[i]; + const tagName = propName(tagObj); + if(tagName === undefined) continue; + + let newJPath = ""; + if (jPath.length === 0) newJPath = tagName + else newJPath = `${jPath}.${tagName}`; + + if (tagName === options.textNodeName) { + let tagText = tagObj[tagName]; + if (!isStopNode(newJPath, options)) { + tagText = options.tagValueProcessor(tagName, tagText); + tagText = replaceEntitiesValue(tagText, options); + } + if (isPreviousElementTag) { + xmlStr += indentation; + } + xmlStr += tagText; + isPreviousElementTag = false; + continue; + } else if (tagName === options.cdataPropName) { + if (isPreviousElementTag) { + xmlStr += indentation; + } + xmlStr += ``; + isPreviousElementTag = false; + continue; + } else if (tagName === options.commentPropName) { + xmlStr += indentation + ``; + isPreviousElementTag = true; + continue; + } else if (tagName[0] === "?") { + const attStr = attr_to_str(tagObj[":@"], options); + const tempInd = tagName === "?xml" ? "" : indentation; + let piTextNodeName = tagObj[tagName][0][options.textNodeName]; + piTextNodeName = piTextNodeName.length !== 0 ? " " + piTextNodeName : ""; //remove extra spacing + xmlStr += tempInd + `<${tagName}${piTextNodeName}${attStr}?>`; + isPreviousElementTag = true; + continue; + } + let newIdentation = indentation; + if (newIdentation !== "") { + newIdentation += options.indentBy; + } + const attStr = attr_to_str(tagObj[":@"], options); + const tagStart = indentation + `<${tagName}${attStr}`; + const tagValue = arrToStr(tagObj[tagName], options, newJPath, newIdentation); + if (options.unpairedTags.indexOf(tagName) !== -1) { + if (options.suppressUnpairedNode) xmlStr += tagStart + ">"; + else xmlStr += tagStart + "/>"; + } else if ((!tagValue || tagValue.length === 0) && options.suppressEmptyNode) { + xmlStr += tagStart + "/>"; + } else if (tagValue && tagValue.endsWith(">")) { + xmlStr += tagStart + `>${tagValue}${indentation}`; + } else { + xmlStr += tagStart + ">"; + if (tagValue && indentation !== "" && (tagValue.includes("/>") || tagValue.includes("`; + } + isPreviousElementTag = true; + } + + return xmlStr; +} + +function propName(obj) { + const keys = Object.keys(obj); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if(!obj.hasOwnProperty(key)) continue; + if (key !== ":@") return key; + } +} + +function attr_to_str(attrMap, options) { + let attrStr = ""; + if (attrMap && !options.ignoreAttributes) { + for (let attr in attrMap) { + if(!attrMap.hasOwnProperty(attr)) continue; + let attrVal = options.attributeValueProcessor(attr, attrMap[attr]); + attrVal = replaceEntitiesValue(attrVal, options); + if (attrVal === true && options.suppressBooleanAttributes) { + attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}`; + } else { + attrStr += ` ${attr.substr(options.attributeNamePrefix.length)}="${attrVal}"`; + } + } + } + return attrStr; +} + +function isStopNode(jPath, options) { + jPath = jPath.substr(0, jPath.length - options.textNodeName.length - 1); + let tagName = jPath.substr(jPath.lastIndexOf(".") + 1); + for (let index in options.stopNodes) { + if (options.stopNodes[index] === jPath || options.stopNodes[index] === "*." + tagName) return true; + } + return false; +} + +function replaceEntitiesValue(textValue, options) { + if (textValue && textValue.length > 0 && options.processEntities) { + for (let i = 0; i < options.entities.length; i++) { + const entity = options.entities[i]; + textValue = textValue.replace(entity.regex, entity.val); + } + } + return textValue; +} +module.exports = toXml; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlbuilder/prettifyJs2Xml.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlbuilder/prettifyJs2Xml.js new file mode 100644 index 0000000..e69de29 diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js new file mode 100644 index 0000000..bfde18e --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js @@ -0,0 +1,153 @@ +const util = require('../util'); + +//TODO: handle comments +function readDocType(xmlData, i){ + + const entities = {}; + if( xmlData[i + 3] === 'O' && + xmlData[i + 4] === 'C' && + xmlData[i + 5] === 'T' && + xmlData[i + 6] === 'Y' && + xmlData[i + 7] === 'P' && + xmlData[i + 8] === 'E') + { + i = i+9; + let angleBracketsCount = 1; + let hasBody = false, comment = false; + let exp = ""; + for(;i') { //Read tag content + if(comment){ + if( xmlData[i - 1] === "-" && xmlData[i - 2] === "-"){ + comment = false; + angleBracketsCount--; + } + }else{ + angleBracketsCount--; + } + if (angleBracketsCount === 0) { + break; + } + }else if( xmlData[i] === '['){ + hasBody = true; + }else{ + exp += xmlData[i]; + } + } + if(angleBracketsCount !== 0){ + throw new Error(`Unclosed DOCTYPE`); + } + }else{ + throw new Error(`Invalid Tag instead of DOCTYPE`); + } + return {entities, i}; +} + +function readEntityExp(xmlData,i){ + //External entities are not supported + // + + //Parameter entities are not supported + // + + //Internal entities are supported + // + + //read EntityName + let entityName = ""; + for (; i < xmlData.length && (xmlData[i] !== "'" && xmlData[i] !== '"' ); i++) { + // if(xmlData[i] === " ") continue; + // else + entityName += xmlData[i]; + } + entityName = entityName.trim(); + if(entityName.indexOf(" ") !== -1) throw new Error("External entites are not supported"); + + //read Entity Value + const startChar = xmlData[i++]; + let val = "" + for (; i < xmlData.length && xmlData[i] !== startChar ; i++) { + val += xmlData[i]; + } + return [entityName, val, i]; +} + +function isComment(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === '-' && + xmlData[i+3] === '-') return true + return false +} +function isEntity(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'E' && + xmlData[i+3] === 'N' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'I' && + xmlData[i+6] === 'T' && + xmlData[i+7] === 'Y') return true + return false +} +function isElement(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'E' && + xmlData[i+3] === 'L' && + xmlData[i+4] === 'E' && + xmlData[i+5] === 'M' && + xmlData[i+6] === 'E' && + xmlData[i+7] === 'N' && + xmlData[i+8] === 'T') return true + return false +} + +function isAttlist(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'A' && + xmlData[i+3] === 'T' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'L' && + xmlData[i+6] === 'I' && + xmlData[i+7] === 'S' && + xmlData[i+8] === 'T') return true + return false +} +function isNotation(xmlData, i){ + if(xmlData[i+1] === '!' && + xmlData[i+2] === 'N' && + xmlData[i+3] === 'O' && + xmlData[i+4] === 'T' && + xmlData[i+5] === 'A' && + xmlData[i+6] === 'T' && + xmlData[i+7] === 'I' && + xmlData[i+8] === 'O' && + xmlData[i+9] === 'N') return true + return false +} + +function validateEntityName(name){ + if (util.isName(name)) + return name; + else + throw new Error(`Invalid entity name ${name}`); +} + +module.exports = readDocType; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js new file mode 100644 index 0000000..bca3776 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js @@ -0,0 +1,48 @@ + +const defaultOptions = { + preserveOrder: false, + attributeNamePrefix: '@_', + attributesGroupName: false, + textNodeName: '#text', + ignoreAttributes: true, + removeNSPrefix: false, // remove NS from tag name or attribute name if true + allowBooleanAttributes: false, //a tag can have attributes without any value + //ignoreRootElement : false, + parseTagValue: true, + parseAttributeValue: false, + trimValues: true, //Trim string values of tag and attributes + cdataPropName: false, + numberParseOptions: { + hex: true, + leadingZeros: true, + eNotation: true + }, + tagValueProcessor: function(tagName, val) { + return val; + }, + attributeValueProcessor: function(attrName, val) { + return val; + }, + stopNodes: [], //nested tags will not be parsed even for errors + alwaysCreateTextNode: false, + isArray: () => false, + commentPropName: false, + unpairedTags: [], + processEntities: true, + htmlEntities: false, + ignoreDeclaration: false, + ignorePiTags: false, + transformTagName: false, + transformAttributeName: false, + updateTag: function(tagName, jPath, attrs){ + return tagName + }, + // skipEmptyListItem: false +}; + +const buildOptions = function(options) { + return Object.assign({}, defaultOptions, options); +}; + +exports.buildOptions = buildOptions; +exports.defaultOptions = defaultOptions; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js new file mode 100644 index 0000000..4f89003 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js @@ -0,0 +1,606 @@ +'use strict'; +///@ts-check + +const util = require('../util'); +const xmlNode = require('./xmlNode'); +const readDocType = require("./DocTypeReader"); +const toNumber = require("strnum"); +const getIgnoreAttributesFn = require('../ignoreAttributes') + +// const regx = +// '<((!\\[CDATA\\[([\\s\\S]*?)(]]>))|((NAME:)?(NAME))([^>]*)>|((\\/)(NAME)\\s*>))([^<]*)' +// .replace(/NAME/g, util.nameRegexp); + +//const tagsRegx = new RegExp("<(\\/?[\\w:\\-\._]+)([^>]*)>(\\s*"+cdataRegx+")*([^<]+)?","g"); +//const tagsRegx = new RegExp("<(\\/?)((\\w*:)?([\\w:\\-\._]+))([^>]*)>([^<]*)("+cdataRegx+"([^<]*))*([^<]+)?","g"); + +class OrderedObjParser{ + constructor(options){ + this.options = options; + this.currentNode = null; + this.tagsNodeStack = []; + this.docTypeEntities = {}; + this.lastEntities = { + "apos" : { regex: /&(apos|#39|#x27);/g, val : "'"}, + "gt" : { regex: /&(gt|#62|#x3E);/g, val : ">"}, + "lt" : { regex: /&(lt|#60|#x3C);/g, val : "<"}, + "quot" : { regex: /&(quot|#34|#x22);/g, val : "\""}, + }; + this.ampEntity = { regex: /&(amp|#38|#x26);/g, val : "&"}; + this.htmlEntities = { + "space": { regex: /&(nbsp|#160);/g, val: " " }, + // "lt" : { regex: /&(lt|#60);/g, val: "<" }, + // "gt" : { regex: /&(gt|#62);/g, val: ">" }, + // "amp" : { regex: /&(amp|#38);/g, val: "&" }, + // "quot" : { regex: /&(quot|#34);/g, val: "\"" }, + // "apos" : { regex: /&(apos|#39);/g, val: "'" }, + "cent" : { regex: /&(cent|#162);/g, val: "¢" }, + "pound" : { regex: /&(pound|#163);/g, val: "£" }, + "yen" : { regex: /&(yen|#165);/g, val: "¥" }, + "euro" : { regex: /&(euro|#8364);/g, val: "€" }, + "copyright" : { regex: /&(copy|#169);/g, val: "©" }, + "reg" : { regex: /&(reg|#174);/g, val: "®" }, + "inr" : { regex: /&(inr|#8377);/g, val: "₹" }, + "num_dec": { regex: /&#([0-9]{1,7});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 10)) }, + "num_hex": { regex: /&#x([0-9a-fA-F]{1,6});/g, val : (_, str) => String.fromCharCode(Number.parseInt(str, 16)) }, + }; + this.addExternalEntities = addExternalEntities; + this.parseXml = parseXml; + this.parseTextData = parseTextData; + this.resolveNameSpace = resolveNameSpace; + this.buildAttributesMap = buildAttributesMap; + this.isItStopNode = isItStopNode; + this.replaceEntitiesValue = replaceEntitiesValue; + this.readStopNodeData = readStopNodeData; + this.saveTextToParentTag = saveTextToParentTag; + this.addChild = addChild; + this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes) + } + +} + +function addExternalEntities(externalEntities){ + const entKeys = Object.keys(externalEntities); + for (let i = 0; i < entKeys.length; i++) { + const ent = entKeys[i]; + this.lastEntities[ent] = { + regex: new RegExp("&"+ent+";","g"), + val : externalEntities[ent] + } + } +} + +/** + * @param {string} val + * @param {string} tagName + * @param {string} jPath + * @param {boolean} dontTrim + * @param {boolean} hasAttributes + * @param {boolean} isLeafNode + * @param {boolean} escapeEntities + */ +function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) { + if (val !== undefined) { + if (this.options.trimValues && !dontTrim) { + val = val.trim(); + } + if(val.length > 0){ + if(!escapeEntities) val = this.replaceEntitiesValue(val); + + const newval = this.options.tagValueProcessor(tagName, val, jPath, hasAttributes, isLeafNode); + if(newval === null || newval === undefined){ + //don't parse + return val; + }else if(typeof newval !== typeof val || newval !== val){ + //overwrite + return newval; + }else if(this.options.trimValues){ + return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions); + }else{ + const trimmedVal = val.trim(); + if(trimmedVal === val){ + return parseValue(val, this.options.parseTagValue, this.options.numberParseOptions); + }else{ + return val; + } + } + } + } +} + +function resolveNameSpace(tagname) { + if (this.options.removeNSPrefix) { + const tags = tagname.split(':'); + const prefix = tagname.charAt(0) === '/' ? '/' : ''; + if (tags[0] === 'xmlns') { + return ''; + } + if (tags.length === 2) { + tagname = prefix + tags[1]; + } + } + return tagname; +} + +//TODO: change regex to capture NS +//const attrsRegx = new RegExp("([\\w\\-\\.\\:]+)\\s*=\\s*(['\"])((.|\n)*?)\\2","gm"); +const attrsRegx = new RegExp('([^\\s=]+)\\s*(=\\s*([\'"])([\\s\\S]*?)\\3)?', 'gm'); + +function buildAttributesMap(attrStr, jPath, tagName) { + if (this.options.ignoreAttributes !== true && typeof attrStr === 'string') { + // attrStr = attrStr.replace(/\r?\n/g, ' '); + //attrStr = attrStr || attrStr.trim(); + + const matches = util.getAllMatches(attrStr, attrsRegx); + const len = matches.length; //don't make it inline + const attrs = {}; + for (let i = 0; i < len; i++) { + const attrName = this.resolveNameSpace(matches[i][1]); + if (this.ignoreAttributesFn(attrName, jPath)) { + continue + } + let oldVal = matches[i][4]; + let aName = this.options.attributeNamePrefix + attrName; + if (attrName.length) { + if (this.options.transformAttributeName) { + aName = this.options.transformAttributeName(aName); + } + if(aName === "__proto__") aName = "#__proto__"; + if (oldVal !== undefined) { + if (this.options.trimValues) { + oldVal = oldVal.trim(); + } + oldVal = this.replaceEntitiesValue(oldVal); + const newVal = this.options.attributeValueProcessor(attrName, oldVal, jPath); + if(newVal === null || newVal === undefined){ + //don't parse + attrs[aName] = oldVal; + }else if(typeof newVal !== typeof oldVal || newVal !== oldVal){ + //overwrite + attrs[aName] = newVal; + }else{ + //parse + attrs[aName] = parseValue( + oldVal, + this.options.parseAttributeValue, + this.options.numberParseOptions + ); + } + } else if (this.options.allowBooleanAttributes) { + attrs[aName] = true; + } + } + } + if (!Object.keys(attrs).length) { + return; + } + if (this.options.attributesGroupName) { + const attrCollection = {}; + attrCollection[this.options.attributesGroupName] = attrs; + return attrCollection; + } + return attrs + } +} + +const parseXml = function(xmlData) { + xmlData = xmlData.replace(/\r\n?/g, "\n"); //TODO: remove this line + const xmlObj = new xmlNode('!xml'); + let currentNode = xmlObj; + let textData = ""; + let jPath = ""; + for(let i=0; i< xmlData.length; i++){//for each char in XML data + const ch = xmlData[i]; + if(ch === '<'){ + // const nextIndex = i+1; + // const _2ndChar = xmlData[nextIndex]; + if( xmlData[i+1] === '/') {//Closing Tag + const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.") + let tagName = xmlData.substring(i+2,closeIndex).trim(); + + if(this.options.removeNSPrefix){ + const colonIndex = tagName.indexOf(":"); + if(colonIndex !== -1){ + tagName = tagName.substr(colonIndex+1); + } + } + + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } + + if(currentNode){ + textData = this.saveTextToParentTag(textData, currentNode, jPath); + } + + //check if last tag of nested tag was unpaired tag + const lastTagName = jPath.substring(jPath.lastIndexOf(".")+1); + if(tagName && this.options.unpairedTags.indexOf(tagName) !== -1 ){ + throw new Error(`Unpaired tag can not be used as closing tag: `); + } + let propIndex = 0 + if(lastTagName && this.options.unpairedTags.indexOf(lastTagName) !== -1 ){ + propIndex = jPath.lastIndexOf('.', jPath.lastIndexOf('.')-1) + this.tagsNodeStack.pop(); + }else{ + propIndex = jPath.lastIndexOf("."); + } + jPath = jPath.substring(0, propIndex); + + currentNode = this.tagsNodeStack.pop();//avoid recursion, set the parent tag scope + textData = ""; + i = closeIndex; + } else if( xmlData[i+1] === '?') { + + let tagData = readTagExp(xmlData,i, false, "?>"); + if(!tagData) throw new Error("Pi Tag is not closed."); + + textData = this.saveTextToParentTag(textData, currentNode, jPath); + if( (this.options.ignoreDeclaration && tagData.tagName === "?xml") || this.options.ignorePiTags){ + + }else{ + + const childNode = new xmlNode(tagData.tagName); + childNode.add(this.options.textNodeName, ""); + + if(tagData.tagName !== tagData.tagExp && tagData.attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagData.tagExp, jPath, tagData.tagName); + } + this.addChild(currentNode, childNode, jPath) + + } + + + i = tagData.closeIndex + 1; + } else if(xmlData.substr(i + 1, 3) === '!--') { + const endIndex = findClosingIndex(xmlData, "-->", i+4, "Comment is not closed.") + if(this.options.commentPropName){ + const comment = xmlData.substring(i + 4, endIndex - 2); + + textData = this.saveTextToParentTag(textData, currentNode, jPath); + + currentNode.add(this.options.commentPropName, [ { [this.options.textNodeName] : comment } ]); + } + i = endIndex; + } else if( xmlData.substr(i + 1, 2) === '!D') { + const result = readDocType(xmlData, i); + this.docTypeEntities = result.entities; + i = result.i; + }else if(xmlData.substr(i + 1, 2) === '![') { + const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2; + const tagExp = xmlData.substring(i + 9,closeIndex); + + textData = this.saveTextToParentTag(textData, currentNode, jPath); + + let val = this.parseTextData(tagExp, currentNode.tagname, jPath, true, false, true, true); + if(val == undefined) val = ""; + + //cdata should be set even if it is 0 length string + if(this.options.cdataPropName){ + currentNode.add(this.options.cdataPropName, [ { [this.options.textNodeName] : tagExp } ]); + }else{ + currentNode.add(this.options.textNodeName, val); + } + + i = closeIndex + 2; + }else {//Opening tag + let result = readTagExp(xmlData,i, this.options.removeNSPrefix); + let tagName= result.tagName; + const rawTagName = result.rawTagName; + let tagExp = result.tagExp; + let attrExpPresent = result.attrExpPresent; + let closeIndex = result.closeIndex; + + if (this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } + + //save text as child node + if (currentNode && textData) { + if(currentNode.tagname !== '!xml'){ + //when nested tag is found + textData = this.saveTextToParentTag(textData, currentNode, jPath, false); + } + } + + //check if last tag was unpaired tag + const lastTag = currentNode; + if(lastTag && this.options.unpairedTags.indexOf(lastTag.tagname) !== -1 ){ + currentNode = this.tagsNodeStack.pop(); + jPath = jPath.substring(0, jPath.lastIndexOf(".")); + } + if(tagName !== xmlObj.tagname){ + jPath += jPath ? "." + tagName : tagName; + } + if (this.isItStopNode(this.options.stopNodes, jPath, tagName)) { + let tagContent = ""; + //self-closing tag + if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){ + if(tagName[tagName.length - 1] === "/"){ //remove trailing '/' + tagName = tagName.substr(0, tagName.length - 1); + jPath = jPath.substr(0, jPath.length - 1); + tagExp = tagName; + }else{ + tagExp = tagExp.substr(0, tagExp.length - 1); + } + i = result.closeIndex; + } + //unpaired tag + else if(this.options.unpairedTags.indexOf(tagName) !== -1){ + + i = result.closeIndex; + } + //normal tag + else{ + //read until closing tag is found + const result = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1); + if(!result) throw new Error(`Unexpected end of ${rawTagName}`); + i = result.i; + tagContent = result.tagContent; + } + + const childNode = new xmlNode(tagName); + if(tagName !== tagExp && attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName); + } + if(tagContent) { + tagContent = this.parseTextData(tagContent, tagName, jPath, true, attrExpPresent, true, true); + } + + jPath = jPath.substr(0, jPath.lastIndexOf(".")); + childNode.add(this.options.textNodeName, tagContent); + + this.addChild(currentNode, childNode, jPath) + }else{ + //selfClosing tag + if(tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1){ + if(tagName[tagName.length - 1] === "/"){ //remove trailing '/' + tagName = tagName.substr(0, tagName.length - 1); + jPath = jPath.substr(0, jPath.length - 1); + tagExp = tagName; + }else{ + tagExp = tagExp.substr(0, tagExp.length - 1); + } + + if(this.options.transformTagName) { + tagName = this.options.transformTagName(tagName); + } + + const childNode = new xmlNode(tagName); + if(tagName !== tagExp && attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName); + } + this.addChild(currentNode, childNode, jPath) + jPath = jPath.substr(0, jPath.lastIndexOf(".")); + } + //opening tag + else{ + const childNode = new xmlNode( tagName); + this.tagsNodeStack.push(currentNode); + + if(tagName !== tagExp && attrExpPresent){ + childNode[":@"] = this.buildAttributesMap(tagExp, jPath, tagName); + } + this.addChild(currentNode, childNode, jPath) + currentNode = childNode; + } + textData = ""; + i = closeIndex; + } + } + }else{ + textData += xmlData[i]; + } + } + return xmlObj.child; +} + +function addChild(currentNode, childNode, jPath){ + const result = this.options.updateTag(childNode.tagname, jPath, childNode[":@"]) + if(result === false){ + }else if(typeof result === "string"){ + childNode.tagname = result + currentNode.addChild(childNode); + }else{ + currentNode.addChild(childNode); + } +} + +const replaceEntitiesValue = function(val){ + + if(this.options.processEntities){ + for(let entityName in this.docTypeEntities){ + const entity = this.docTypeEntities[entityName]; + val = val.replace( entity.regx, entity.val); + } + for(let entityName in this.lastEntities){ + const entity = this.lastEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + if(this.options.htmlEntities){ + for(let entityName in this.htmlEntities){ + const entity = this.htmlEntities[entityName]; + val = val.replace( entity.regex, entity.val); + } + } + val = val.replace( this.ampEntity.regex, this.ampEntity.val); + } + return val; +} +function saveTextToParentTag(textData, currentNode, jPath, isLeafNode) { + if (textData) { //store previously collected data as textNode + if(isLeafNode === undefined) isLeafNode = currentNode.child.length === 0 + + textData = this.parseTextData(textData, + currentNode.tagname, + jPath, + false, + currentNode[":@"] ? Object.keys(currentNode[":@"]).length !== 0 : false, + isLeafNode); + + if (textData !== undefined && textData !== "") + currentNode.add(this.options.textNodeName, textData); + textData = ""; + } + return textData; +} + +//TODO: use jPath to simplify the logic +/** + * + * @param {string[]} stopNodes + * @param {string} jPath + * @param {string} currentTagName + */ +function isItStopNode(stopNodes, jPath, currentTagName){ + const allNodesExp = "*." + currentTagName; + for (const stopNodePath in stopNodes) { + const stopNodeExp = stopNodes[stopNodePath]; + if( allNodesExp === stopNodeExp || jPath === stopNodeExp ) return true; + } + return false; +} + +/** + * Returns the tag Expression and where it is ending handling single-double quotes situation + * @param {string} xmlData + * @param {number} i starting index + * @returns + */ +function tagExpWithClosingIndex(xmlData, i, closingChar = ">"){ + let attrBoundary; + let tagExp = ""; + for (let index = i; index < xmlData.length; index++) { + let ch = xmlData[index]; + if (attrBoundary) { + if (ch === attrBoundary) attrBoundary = "";//reset + } else if (ch === '"' || ch === "'") { + attrBoundary = ch; + } else if (ch === closingChar[0]) { + if(closingChar[1]){ + if(xmlData[index + 1] === closingChar[1]){ + return { + data: tagExp, + index: index + } + } + }else{ + return { + data: tagExp, + index: index + } + } + } else if (ch === '\t') { + ch = " " + } + tagExp += ch; + } +} + +function findClosingIndex(xmlData, str, i, errMsg){ + const closingIndex = xmlData.indexOf(str, i); + if(closingIndex === -1){ + throw new Error(errMsg) + }else{ + return closingIndex + str.length - 1; + } +} + +function readTagExp(xmlData,i, removeNSPrefix, closingChar = ">"){ + const result = tagExpWithClosingIndex(xmlData, i+1, closingChar); + if(!result) return; + let tagExp = result.data; + const closeIndex = result.index; + const separatorIndex = tagExp.search(/\s/); + let tagName = tagExp; + let attrExpPresent = true; + if(separatorIndex !== -1){//separate tag name and attributes expression + tagName = tagExp.substring(0, separatorIndex); + tagExp = tagExp.substring(separatorIndex + 1).trimStart(); + } + + const rawTagName = tagName; + if(removeNSPrefix){ + const colonIndex = tagName.indexOf(":"); + if(colonIndex !== -1){ + tagName = tagName.substr(colonIndex+1); + attrExpPresent = tagName !== result.data.substr(colonIndex + 1); + } + } + + return { + tagName: tagName, + tagExp: tagExp, + closeIndex: closeIndex, + attrExpPresent: attrExpPresent, + rawTagName: rawTagName, + } +} +/** + * find paired tag for a stop node + * @param {string} xmlData + * @param {string} tagName + * @param {number} i + */ +function readStopNodeData(xmlData, tagName, i){ + const startIndex = i; + // Starting at 1 since we already have an open tag + let openTagCount = 1; + + for (; i < xmlData.length; i++) { + if( xmlData[i] === "<"){ + if (xmlData[i+1] === "/") {//close tag + const closeIndex = findClosingIndex(xmlData, ">", i, `${tagName} is not closed`); + let closeTagName = xmlData.substring(i+2,closeIndex).trim(); + if(closeTagName === tagName){ + openTagCount--; + if (openTagCount === 0) { + return { + tagContent: xmlData.substring(startIndex, i), + i : closeIndex + } + } + } + i=closeIndex; + } else if(xmlData[i+1] === '?') { + const closeIndex = findClosingIndex(xmlData, "?>", i+1, "StopNode is not closed.") + i=closeIndex; + } else if(xmlData.substr(i + 1, 3) === '!--') { + const closeIndex = findClosingIndex(xmlData, "-->", i+3, "StopNode is not closed.") + i=closeIndex; + } else if(xmlData.substr(i + 1, 2) === '![') { + const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2; + i=closeIndex; + } else { + const tagData = readTagExp(xmlData, i, '>') + + if (tagData) { + const openTagName = tagData && tagData.tagName; + if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length-1] !== "/") { + openTagCount++; + } + i=tagData.closeIndex; + } + } + } + }//end for loop +} + +function parseValue(val, shouldParse, options) { + if (shouldParse && typeof val === 'string') { + //console.log(options) + const newval = val.trim(); + if(newval === 'true' ) return true; + else if(newval === 'false' ) return false; + else return toNumber(val, options); + } else { + if (util.isExist(val)) { + return val; + } else { + return ''; + } + } +} + + +module.exports = OrderedObjParser; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js new file mode 100644 index 0000000..ffaf59b --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/XMLParser.js @@ -0,0 +1,58 @@ +const { buildOptions} = require("./OptionsBuilder"); +const OrderedObjParser = require("./OrderedObjParser"); +const { prettify} = require("./node2json"); +const validator = require('../validator'); + +class XMLParser{ + + constructor(options){ + this.externalEntities = {}; + this.options = buildOptions(options); + + } + /** + * Parse XML dats to JS object + * @param {string|Buffer} xmlData + * @param {boolean|Object} validationOption + */ + parse(xmlData,validationOption){ + if(typeof xmlData === "string"){ + }else if( xmlData.toString){ + xmlData = xmlData.toString(); + }else{ + throw new Error("XML data is accepted in String or Bytes[] form.") + } + if( validationOption){ + if(validationOption === true) validationOption = {}; //validate with default options + + const result = validator.validate(xmlData, validationOption); + if (result !== true) { + throw Error( `${result.err.msg}:${result.err.line}:${result.err.col}` ) + } + } + const orderedObjParser = new OrderedObjParser(this.options); + orderedObjParser.addExternalEntities(this.externalEntities); + const orderedResult = orderedObjParser.parseXml(xmlData); + if(this.options.preserveOrder || orderedResult === undefined) return orderedResult; + else return prettify(orderedResult, this.options); + } + + /** + * Add Entity which is not by default supported by this library + * @param {string} key + * @param {string} value + */ + addEntity(key, value){ + if(value.indexOf("&") !== -1){ + throw new Error("Entity value can't have '&'") + }else if(key.indexOf("&") !== -1 || key.indexOf(";") !== -1){ + throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for ' '") + }else if(value === "&"){ + throw new Error("An entity with value '&' is not permitted"); + }else{ + this.externalEntities[key] = value; + } + } +} + +module.exports = XMLParser; \ No newline at end of file diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/node2json.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/node2json.js new file mode 100644 index 0000000..3045573 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/node2json.js @@ -0,0 +1,113 @@ +'use strict'; + +/** + * + * @param {array} node + * @param {any} options + * @returns + */ +function prettify(node, options){ + return compress( node, options); +} + +/** + * + * @param {array} arr + * @param {object} options + * @param {string} jPath + * @returns object + */ +function compress(arr, options, jPath){ + let text; + const compressedObj = {}; + for (let i = 0; i < arr.length; i++) { + const tagObj = arr[i]; + const property = propName(tagObj); + let newJpath = ""; + if(jPath === undefined) newJpath = property; + else newJpath = jPath + "." + property; + + if(property === options.textNodeName){ + if(text === undefined) text = tagObj[property]; + else text += "" + tagObj[property]; + }else if(property === undefined){ + continue; + }else if(tagObj[property]){ + + let val = compress(tagObj[property], options, newJpath); + const isLeaf = isLeafTag(val, options); + + if(tagObj[":@"]){ + assignAttributes( val, tagObj[":@"], newJpath, options); + }else if(Object.keys(val).length === 1 && val[options.textNodeName] !== undefined && !options.alwaysCreateTextNode){ + val = val[options.textNodeName]; + }else if(Object.keys(val).length === 0){ + if(options.alwaysCreateTextNode) val[options.textNodeName] = ""; + else val = ""; + } + + if(compressedObj[property] !== undefined && compressedObj.hasOwnProperty(property)) { + if(!Array.isArray(compressedObj[property])) { + compressedObj[property] = [ compressedObj[property] ]; + } + compressedObj[property].push(val); + }else{ + //TODO: if a node is not an array, then check if it should be an array + //also determine if it is a leaf node + if (options.isArray(property, newJpath, isLeaf )) { + compressedObj[property] = [val]; + }else{ + compressedObj[property] = val; + } + } + } + + } + // if(text && text.length > 0) compressedObj[options.textNodeName] = text; + if(typeof text === "string"){ + if(text.length > 0) compressedObj[options.textNodeName] = text; + }else if(text !== undefined) compressedObj[options.textNodeName] = text; + return compressedObj; +} + +function propName(obj){ + const keys = Object.keys(obj); + for (let i = 0; i < keys.length; i++) { + const key = keys[i]; + if(key !== ":@") return key; + } +} + +function assignAttributes(obj, attrMap, jpath, options){ + if (attrMap) { + const keys = Object.keys(attrMap); + const len = keys.length; //don't make it inline + for (let i = 0; i < len; i++) { + const atrrName = keys[i]; + if (options.isArray(atrrName, jpath + "." + atrrName, true, true)) { + obj[atrrName] = [ attrMap[atrrName] ]; + } else { + obj[atrrName] = attrMap[atrrName]; + } + } + } +} + +function isLeafTag(obj, options){ + const { textNodeName } = options; + const propCount = Object.keys(obj).length; + + if (propCount === 0) { + return true; + } + + if ( + propCount === 1 && + (obj[textNodeName] || typeof obj[textNodeName] === "boolean" || obj[textNodeName] === 0) + ) { + return true; + } + + return false; +} +exports.prettify = prettify; diff --git a/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js new file mode 100644 index 0000000..9319524 --- /dev/null +++ b/tools/join-backups/node_modules/fast-xml-parser/src/xmlparser/xmlNode.js @@ -0,0 +1,25 @@ +'use strict'; + +class XmlNode{ + constructor(tagname) { + this.tagname = tagname; + this.child = []; //nested tags, text, cdata, comments in order + this[":@"] = {}; //attributes map + } + add(key,val){ + // this.child.push( {name : key, val: val, isCdata: isCdata }); + if(key === "__proto__") key = "#__proto__"; + this.child.push( {[key]: val }); + } + addChild(node) { + if(node.tagname === "__proto__") node.tagname = "#__proto__"; + if(node[":@"] && Object.keys(node[":@"]).length > 0){ + this.child.push( { [node.tagname]: node.child, [":@"]: node[":@"] }); + }else{ + this.child.push( { [node.tagname]: node.child }); + } + }; +}; + + +module.exports = XmlNode; \ No newline at end of file diff --git a/tools/join-backups/node_modules/strnum/.vscode/launch.json b/tools/join-backups/node_modules/strnum/.vscode/launch.json new file mode 100644 index 0000000..b87b349 --- /dev/null +++ b/tools/join-backups/node_modules/strnum/.vscode/launch.json @@ -0,0 +1,25 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Jasmine Tests", + "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js", + "args": [ + "${workspaceFolder}/spec/attr_spec.js" + ], + "internalConsoleOptions": "openOnSessionStart" + },{ + "type": "node", + "request": "launch", + "name": "Jasmine Tests current test file", + "program": "${workspaceFolder}/node_modules/jasmine/bin/jasmine.js", + "args": [ + "${file}" + ], + "internalConsoleOptions": "openOnSessionStart" + } + ] + +} \ No newline at end of file diff --git a/tools/join-backups/node_modules/strnum/CHANGELOG.md b/tools/join-backups/node_modules/strnum/CHANGELOG.md new file mode 100644 index 0000000..582e460 --- /dev/null +++ b/tools/join-backups/node_modules/strnum/CHANGELOG.md @@ -0,0 +1,22 @@ + +**1.1.2 / 2025-02-27** +- fix skiplike for 0 + +**1.1.1 / 2025-02-21** +- All recent fixes of version 2 + +**2.0.4 / 2025-02-20** +- remove console log + +**2.0.3 / 2025-02-20** +- fix for string which are falsly identified as e-notation + +**2.0.1 / 2025-02-20** +- fix: handle only zeros +- fix: return original string when NaN + +**2.0.0 / 2025-02-20** +- Migrating to ESM modules. No functional change + +**1.1.0 / 2025-02-20** +- fix (#9): support missing floating point and e notations \ No newline at end of file diff --git a/tools/join-backups/node_modules/strnum/LICENSE b/tools/join-backups/node_modules/strnum/LICENSE new file mode 100644 index 0000000..6450554 --- /dev/null +++ b/tools/join-backups/node_modules/strnum/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Natural Intelligence + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/join-backups/node_modules/strnum/README.md b/tools/join-backups/node_modules/strnum/README.md new file mode 100644 index 0000000..419e8ef --- /dev/null +++ b/tools/join-backups/node_modules/strnum/README.md @@ -0,0 +1,97 @@ +# strnum +Parse string into Number based on configuration + +## Users + + + + + +Many React Native projects and plugins + +## Usage + +```bash +npm install strnum +``` +```js +const toNumber = require("strnum"); + +toNumber(undefined) // undefined +toNumber(null)) //null +toNumber("")) // "" +toNumber("string"); //"string") +toNumber("12,12"); //"12,12") +toNumber("12 12"); //"12 12") +toNumber("12-12"); //"12-12") +toNumber("12.12.12"); //"12.12.12") +toNumber("0x2f"); //47) +toNumber("-0x2f"); //-47) +toNumber("0x2f", { hex : true}); //47) +toNumber("-0x2f", { hex : true}); //-47) +toNumber("0x2f", { hex : false}); //"0x2f") +toNumber("-0x2f", { hex : false}); //"-0x2f") +toNumber("06"); //6) +toNumber("06", { leadingZeros : true}); //6) +toNumber("06", { leadingZeros : false}); //"06") + +toNumber("006"); //6) +toNumber("006", { leadingZeros : true}); //6) +toNumber("006", { leadingZeros : false}); //"006") +toNumber("0.0"); //0) +toNumber("00.00"); //0) +toNumber("0.06"); //0.06) +toNumber("00.6"); //0.6) +toNumber(".006"); //0.006) +toNumber("6.0"); //6) +toNumber("06.0"); //6) + +toNumber("0.0", { leadingZeros : false}); //0) +toNumber("00.00", { leadingZeros : false}); //"00.00") +toNumber("0.06", { leadingZeros : false}); //0.06) +toNumber("00.6", { leadingZeros : false}); //"00.6") +toNumber(".006", { leadingZeros : false}); //0.006) +toNumber("6.0" , { leadingZeros : false}); //6) +toNumber("06.0" , { leadingZeros : false}); //"06.0") +toNumber("-06"); //-6) +toNumber("-06", { leadingZeros : true}); //-6) +toNumber("-06", { leadingZeros : false}); //"-06") + +toNumber("-0.0"); //-0) +toNumber("-00.00"); //-0) +toNumber("-0.06"); //-0.06) +toNumber("-00.6"); //-0.6) +toNumber("-.006"); //-0.006) +toNumber("-6.0"); //-6) +toNumber("-06.0"); //-6) + +toNumber("-0.0" , { leadingZeros : false}); //-0) +toNumber("-00.00", { leadingZeros : false}); //"-00.00") +toNumber("-0.06", { leadingZeros : false}); //-0.06) +toNumber("-00.6", { leadingZeros : false}); //"-00.6") +toNumber("-.006", {leadingZeros : false}); //-0.006) +toNumber("-6.0" , { leadingZeros : false}); //-6) +toNumber("-06.0" , { leadingZeros : false}); //"-06.0") +toNumber("420926189200190257681175017717") ; //4.209261892001902e+29) +toNumber("000000000000000000000000017717" , { leadingZeros : false}); //"000000000000000000000000017717") +toNumber("000000000000000000000000017717" , { leadingZeros : true}); //17717) +toNumber("01.0e2" , { leadingZeros : false}); //"01.0e2") +toNumber("-01.0e2" , { leadingZeros : false}); //"-01.0e2") +toNumber("01.0e2") ; //100) +toNumber("-01.0e2") ; //-100) +toNumber("1.0e2") ; //100) + +toNumber("-1.0e2") ; //-100) +toNumber("1.0e-2"); //0.01) + +toNumber("+1212121212"); // 1212121212 +toNumber("+1212121212", { skipLike: /\+[0-9]{10}/} )); //"+1212121212" +``` + +Supported Options +```js +hex: true, //when hexadecimal string should be parsed +leadingZeros: true, //when number with leading zeros like 08 should be parsed. 0.0 is not impacted +eNotation: true, //when number with eNotation or number parsed in eNotation should be considered +skipLike: /regex/ //when string should not be parsed when it matches the specified regular expression +``` diff --git a/tools/join-backups/node_modules/strnum/package.json b/tools/join-backups/node_modules/strnum/package.json new file mode 100644 index 0000000..90a1b96 --- /dev/null +++ b/tools/join-backups/node_modules/strnum/package.json @@ -0,0 +1,30 @@ +{ + "name": "strnum", + "version": "1.1.2", + "description": "Parse String to Number based on configuration", + "main": "strnum.js", + "scripts": { + "test": "jasmine strnum.test.js" + }, + "keywords": [ + "string", + "number", + "parse", + "convert" + ], + "repository": { + "type": "git", + "url": "https://github.com/NaturalIntelligence/strnum" + }, + "author": "Amit Gupta (https://amitkumargupta.work/)", + "license": "MIT", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "devDependencies": { + "jasmine": "^5.6.0" + } +} diff --git a/tools/join-backups/node_modules/strnum/strnum.js b/tools/join-backups/node_modules/strnum/strnum.js new file mode 100644 index 0000000..c3bd08e --- /dev/null +++ b/tools/join-backups/node_modules/strnum/strnum.js @@ -0,0 +1,111 @@ +const hexRegex = /^[-+]?0x[a-fA-F0-9]+$/; +const numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/; +// const octRegex = /^0x[a-z0-9]+/; +// const binRegex = /0x[a-z0-9]+/; + + +const consider = { + hex : true, + // oct: false, + leadingZeros: true, + decimalPoint: "\.", + eNotation: true, + //skipLike: /regex/ +}; + +function toNumber(str, options = {}){ + options = Object.assign({}, consider, options ); + if(!str || typeof str !== "string" ) return str; + + let trimmedStr = str.trim(); + + if(options.skipLike !== undefined && options.skipLike.test(trimmedStr)) return str; + else if(str==="0") return 0; + else if (options.hex && hexRegex.test(trimmedStr)) { + return parse_int(trimmedStr, 16); + // }else if (options.oct && octRegex.test(str)) { + // return Number.parseInt(val, 8); + }else if (trimmedStr.search(/[eE]/)!== -1) { //eNotation + const notation = trimmedStr.match(/^([-\+])?(0*)([0-9]*(\.[0-9]*)?[eE][-\+]?[0-9]+)$/); + // +00.123 => [ , '+', '00', '.123', .. + if(notation){ + // console.log(notation) + if(options.leadingZeros){ //accept with leading zeros + trimmedStr = (notation[1] || "") + notation[3]; + }else{ + if(notation[2] === "0" && notation[3][0]=== "."){ //valid number + }else{ + return str; + } + } + return options.eNotation ? Number(trimmedStr) : str; + }else{ + return str; + } + // }else if (options.parseBin && binRegex.test(str)) { + // return Number.parseInt(val, 2); + }else{ + //separate negative sign, leading zeros, and rest number + const match = numRegex.exec(trimmedStr); + // +00.123 => [ , '+', '00', '.123', .. + if(match){ + const sign = match[1]; + const leadingZeros = match[2]; + let numTrimmedByZeros = trimZeros(match[3]); //complete num without leading zeros + //trim ending zeros for floating number + + if(!options.leadingZeros && leadingZeros.length > 0 && sign && trimmedStr[2] !== ".") return str; //-0123 + else if(!options.leadingZeros && leadingZeros.length > 0 && !sign && trimmedStr[1] !== ".") return str; //0123 + else if(options.leadingZeros && leadingZeros===str) return 0; //00 + + else{//no leading zeros or leading zeros are allowed + const num = Number(trimmedStr); + const numStr = "" + num; + + if(numStr.search(/[eE]/) !== -1){ //given number is long and parsed to eNotation + if(options.eNotation) return num; + else return str; + }else if(trimmedStr.indexOf(".") !== -1){ //floating number + if(numStr === "0" && (numTrimmedByZeros === "") ) return num; //0.0 + else if(numStr === numTrimmedByZeros) return num; //0.456. 0.79000 + else if( sign && numStr === "-"+numTrimmedByZeros) return num; + else return str; + } + + if(leadingZeros){ + return (numTrimmedByZeros === numStr) || (sign+numTrimmedByZeros === numStr) ? num : str + }else { + return (trimmedStr === numStr) || (trimmedStr === sign+numStr) ? num : str + } + } + }else{ //non-numeric string + return str; + } + } +} + +/** + * + * @param {string} numStr without leading zeros + * @returns + */ +function trimZeros(numStr){ + if(numStr && numStr.indexOf(".") !== -1){//float + numStr = numStr.replace(/0+$/, ""); //remove ending zeros + if(numStr === ".") numStr = "0"; + else if(numStr[0] === ".") numStr = "0"+numStr; + else if(numStr[numStr.length-1] === ".") numStr = numStr.substr(0,numStr.length-1); + return numStr; + } + return numStr; +} + +function parse_int(numStr, base){ + //polyfill + if(parseInt) return parseInt(numStr, base); + else if(Number.parseInt) return Number.parseInt(numStr, base); + else if(window && window.parseInt) return window.parseInt(numStr, base); + else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported") +} + +module.exports = toNumber; \ No newline at end of file diff --git a/tools/join-backups/node_modules/strnum/strnum.test.js b/tools/join-backups/node_modules/strnum/strnum.test.js new file mode 100644 index 0000000..c476614 --- /dev/null +++ b/tools/join-backups/node_modules/strnum/strnum.test.js @@ -0,0 +1,165 @@ +const toNumber = require("./strnum.js"); + +describe("Should convert all the valid numeric strings to number", () => { + it("should return undefined, null, empty string, or non-numeric as it is", () => { + expect(toNumber(undefined)).not.toBeDefined(); + expect(toNumber(null)).toEqual(null); + expect(toNumber("")).toEqual(""); + expect(toNumber("string")).toEqual("string"); + expect(toNumber("e89794659669cb7bb967db73a7ea6889c3891727")).toEqual("e89794659669cb7bb967db73a7ea6889c3891727"); + + }); + it("should not parse number with spaces or comma", () => { + expect(toNumber("12,12")).toEqual("12,12"); + expect(toNumber("12 12")).toEqual("12 12"); + expect(toNumber("12-12")).toEqual("12-12"); + expect(toNumber("12.12.12")).toEqual("12.12.12"); + }) + it("should consider + sign", () => { + expect(toNumber("+12")).toEqual(12); + expect(toNumber("+ 12")).toEqual("+ 12"); + expect(toNumber("12+12")).toEqual("12+12"); + expect(toNumber("1212+")).toEqual("1212+"); + }) + it("should parse hexadecimal values", () => { + expect(toNumber("0x2f")).toEqual(47); + expect(toNumber("-0x2f")).toEqual(-47); + expect(toNumber("0x2f", { hex : true})).toEqual(47); + expect(toNumber("-0x2f", { hex : true})).toEqual(-47); + expect(toNumber("0x2f", { hex : false})).toEqual("0x2f"); + expect(toNumber("-0x2f", { hex : false})).toEqual("-0x2f"); + }) + it("should not parse strings with 0x embedded", () => { + expect(toNumber("0xzz")).toEqual("0xzz"); + expect(toNumber("iweraf0x123qwerqwer")).toEqual("iweraf0x123qwerqwer"); + expect(toNumber("1230x55")).toEqual("1230x55"); + expect(toNumber("JVBERi0xLjMNCiXi48")).toEqual("JVBERi0xLjMNCiXi48"); + }) + it("leading zeros", () => { + expect(toNumber("0")).toEqual(0); + expect(toNumber("00")).toEqual(0); + expect(toNumber("00.0")).toEqual(0); + + expect(toNumber("0",{ leadingZeros : false})).toEqual(0); + expect(toNumber("00",{ leadingZeros : false})).toEqual("00"); + expect(toNumber("00.0",{ leadingZeros : false})).toEqual("00.0"); + + expect(toNumber("06")).toEqual(6); + expect(toNumber("06", { leadingZeros : true})).toEqual(6); + expect(toNumber("06", { leadingZeros : false})).toEqual("06"); + + expect(toNumber("006")).toEqual(6); + expect(toNumber("006", { leadingZeros : true})).toEqual(6); + expect(toNumber("006", { leadingZeros : false})).toEqual("006"); + + expect(toNumber("000000000000000000000000017717" , { leadingZeros : false})).toEqual("000000000000000000000000017717"); + expect(toNumber("000000000000000000000000017717" , { leadingZeros : true})).toEqual(17717); + expect(toNumber("020211201030005811824") ).toEqual("020211201030005811824"); + expect(toNumber("0420926189200190257681175017717") ).toEqual(4.209261892001902e+29); + }) + it("invalid floating number", () => { + expect(toNumber("20.21.030") ).toEqual("20.21.030"); + expect(toNumber("0.21.030") ).toEqual("0.21.030"); + expect(toNumber("0.21.") ).toEqual("0.21."); + }); + it("floating point and leading zeros", () => { + expect(toNumber("0.")).toEqual(0); + expect(toNumber("+0.")).toEqual(0); + expect(toNumber("-0.")).toEqual(-0); + expect(toNumber("1.") ).toEqual(1); + expect(toNumber("00.00")).toEqual(0); + expect(toNumber("0.06")).toEqual(0.06); + expect(toNumber("00.6")).toEqual(0.6); + expect(toNumber(".006")).toEqual(0.006); + expect(toNumber("6.0")).toEqual(6); + expect(toNumber("06.0")).toEqual(6); + + expect(toNumber("0.0", { leadingZeros : false})).toEqual(0); + expect(toNumber("00.00", { leadingZeros : false})).toEqual("00.00"); + expect(toNumber("0.06", { leadingZeros : false})).toEqual(0.06); + expect(toNumber("00.6", { leadingZeros : false})).toEqual("00.6"); + expect(toNumber(".006", { leadingZeros : false})).toEqual(0.006); + expect(toNumber("6.0" , { leadingZeros : false})).toEqual(6); + expect(toNumber("06.0" , { leadingZeros : false})).toEqual("06.0"); + }) + it("negative number leading zeros", () => { + expect(toNumber("+06")).toEqual(6); + expect(toNumber("-06")).toEqual(-6); + expect(toNumber("-06", { leadingZeros : true})).toEqual(-6); + expect(toNumber("-06", { leadingZeros : false})).toEqual("-06"); + + expect(toNumber("-0.0")).toEqual(-0); + expect(toNumber("-00.00")).toEqual(-0); + expect(toNumber("-0.06")).toEqual(-0.06); + expect(toNumber("-00.6")).toEqual(-0.6); + expect(toNumber("-.006")).toEqual(-0.006); + expect(toNumber("-6.0")).toEqual(-6); + expect(toNumber("-06.0")).toEqual(-6); + + expect(toNumber("-0.0" , { leadingZeros : false})).toEqual(-0); + expect(toNumber("-00.00", { leadingZeros : false})).toEqual("-00.00"); + expect(toNumber("-0.06", { leadingZeros : false})).toEqual(-0.06); + expect(toNumber("-00.6", { leadingZeros : false})).toEqual("-00.6"); + expect(toNumber("-.006", {leadingZeros : false})).toEqual(-0.006); + expect(toNumber("-6.0" , { leadingZeros : false})).toEqual(-6); + expect(toNumber("-06.0" , { leadingZeros : false})).toEqual("-06.0"); + }) + it("long number", () => { + expect(toNumber("020211201030005811824") ).toEqual("020211201030005811824"); + expect(toNumber("20211201030005811824") ).toEqual("20211201030005811824"); + expect(toNumber("20.211201030005811824") ).toEqual("20.211201030005811824"); + expect(toNumber("0.211201030005811824") ).toEqual("0.211201030005811824"); + }); + it("scientific notation", () => { + expect(toNumber("01.0e2" , { leadingZeros : false})).toEqual("01.0e2"); + expect(toNumber("-01.0e2" , { leadingZeros : false})).toEqual("-01.0e2"); + expect(toNumber("01.0e2") ).toEqual(100); + expect(toNumber("-01.0e2") ).toEqual(-100); + expect(toNumber("1.0e2") ).toEqual(100); + + expect(toNumber("-1.0e2") ).toEqual(-100); + expect(toNumber("1.0e-2")).toEqual(0.01); + + expect(toNumber("420926189200190257681175017717") ).toEqual(4.209261892001902e+29); + expect(toNumber("420926189200190257681175017717" , { eNotation: false} )).toEqual("420926189200190257681175017717"); + + expect(toNumber("1e-2")).toEqual(0.01); + expect(toNumber("1e+2")).toEqual(100); + expect(toNumber("1.e+2")).toEqual(100); + }); + + it("scientific notation with upper E", () => { + expect(toNumber("01.0E2" , { leadingZeros : false})).toEqual("01.0E2"); + expect(toNumber("-01.0E2" , { leadingZeros : false})).toEqual("-01.0E2"); + expect(toNumber("01.0E2") ).toEqual(100); + expect(toNumber("-01.0E2") ).toEqual(-100); + expect(toNumber("1.0E2") ).toEqual(100); + + expect(toNumber("-1.0E2") ).toEqual(-100); + expect(toNumber("1.0E-2")).toEqual(0.01); + }); + + it("should skip matching pattern", () => { + expect(toNumber("0", { skipLike: /.*/ })).toEqual("0"); + expect(toNumber("+12", { skipLike: /\+[0-9]{10}/} )).toEqual(12); + expect(toNumber("12+12", { skipLike: /\+[0-9]{10}/} )).toEqual("12+12"); + expect(toNumber("12+1212121212", { skipLike: /\+[0-9]{10}/} )).toEqual("12+1212121212"); + expect(toNumber("+1212121212") ).toEqual(1212121212); + expect(toNumber("+1212121212", { skipLike: /\+[0-9]{10}/} )).toEqual("+1212121212"); + }) + it("should not change string if not number", () => { + expect(toNumber("+12 12")).toEqual("+12 12"); + expect(toNumber(" +12 12 ")).toEqual(" +12 12 "); + }) + it("should ignore sorrounded spaces ", () => { + expect(toNumber(" +1212 ")).toEqual(1212); + }) + + it("negative numbers", () => { + expect(toNumber("+1212")).toEqual(1212); + expect(toNumber("+12.12")).toEqual(12.12); + expect(toNumber("-12.12")).toEqual(-12.12); + expect(toNumber("-012.12")).toEqual(-12.12); + expect(toNumber("-012.12")).toEqual(-12.12); + }) +}); diff --git a/tools/join-backups/package-lock.json b/tools/join-backups/package-lock.json new file mode 100644 index 0000000..afe4f2c --- /dev/null +++ b/tools/join-backups/package-lock.json @@ -0,0 +1,268 @@ +{ + "name": "join-backups", + "version": "0.1.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "join-backups", + "version": "0.1.0", + "dependencies": { + "fast-xml-parser": "^4.0.12" + }, + "bin": { + "join-backups": "index.js" + }, + "devDependencies": { + "@tauri-apps/cli": "^2.9.6" + } + }, + "node_modules/@tauri-apps/cli": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-2.9.6.tgz", + "integrity": "sha512-3xDdXL5omQ3sPfBfdC8fCtDKcnyV7OqyzQgfyT5P3+zY6lcPqIYKQBvUasNvppi21RSdfhy44ttvJmftb0PCDw==", + "dev": true, + "license": "Apache-2.0 OR MIT", + "bin": { + "tauri": "tauri.js" + }, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/tauri" + }, + "optionalDependencies": { + "@tauri-apps/cli-darwin-arm64": "2.9.6", + "@tauri-apps/cli-darwin-x64": "2.9.6", + "@tauri-apps/cli-linux-arm-gnueabihf": "2.9.6", + "@tauri-apps/cli-linux-arm64-gnu": "2.9.6", + "@tauri-apps/cli-linux-arm64-musl": "2.9.6", + "@tauri-apps/cli-linux-riscv64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-gnu": "2.9.6", + "@tauri-apps/cli-linux-x64-musl": "2.9.6", + "@tauri-apps/cli-win32-arm64-msvc": "2.9.6", + "@tauri-apps/cli-win32-ia32-msvc": "2.9.6", + "@tauri-apps/cli-win32-x64-msvc": "2.9.6" + } + }, + "node_modules/@tauri-apps/cli-darwin-arm64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.9.6.tgz", + "integrity": "sha512-gf5no6N9FCk1qMrti4lfwP77JHP5haASZgVbBgpZG7BUepB3fhiLCXGUK8LvuOjP36HivXewjg72LTnPDScnQQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-darwin-x64": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.9.6.tgz", + "integrity": "sha512-oWh74WmqbERwwrwcueJyY6HYhgCksUc6NT7WKeXyrlY/FPmNgdyQAgcLuTSkhRFuQ6zh4Np1HZpOqCTpeZBDcw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm-gnueabihf": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.9.6.tgz", + "integrity": "sha512-/zde3bFroFsNXOHN204DC2qUxAcAanUjVXXSdEGmhwMUZeAQalNj5cz2Qli2elsRjKN/hVbZOJj0gQ5zaYUjSg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.9.6.tgz", + "integrity": "sha512-pvbljdhp9VOo4RnID5ywSxgBs7qiylTPlK56cTk7InR3kYSTJKYMqv/4Q/4rGo/mG8cVppesKIeBMH42fw6wjg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-arm64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.9.6.tgz", + "integrity": "sha512-02TKUndpodXBCR0oP//6dZWGYcc22Upf2eP27NvC6z0DIqvkBBFziQUcvi2n6SrwTRL0yGgQjkm9K5NIn8s6jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-riscv64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.9.6.tgz", + "integrity": "sha512-fmp1hnulbqzl1GkXl4aTX9fV+ubHw2LqlLH1PE3BxZ11EQk+l/TmiEongjnxF0ie4kV8DQfDNJ1KGiIdWe1GvQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-gnu": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.9.6.tgz", + "integrity": "sha512-vY0le8ad2KaV1PJr+jCd8fUF9VOjwwQP/uBuTJvhvKTloEwxYA/kAjKK9OpIslGA9m/zcnSo74czI6bBrm2sYA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-linux-x64-musl": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.9.6.tgz", + "integrity": "sha512-TOEuB8YCFZTWVDzsO2yW0+zGcoMiPPwcUgdnW1ODnmgfwccpnihDRoks+ABT1e3fHb1ol8QQWsHSCovb3o2ENQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-arm64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.9.6.tgz", + "integrity": "sha512-ujmDGMRc4qRLAnj8nNG26Rlz9klJ0I0jmZs2BPpmNNf0gM/rcVHhqbEkAaHPTBVIrtUdf7bGvQAD2pyIiUrBHQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-ia32-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.9.6.tgz", + "integrity": "sha512-S4pT0yAJgFX8QRCyKA1iKjZ9Q/oPjCZf66A/VlG5Yw54Nnr88J1uBpmenINbXxzyhduWrIXBaUbEY1K80ZbpMg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@tauri-apps/cli-win32-x64-msvc": { + "version": "2.9.6", + "resolved": "https://registry.npmjs.org/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.9.6.tgz", + "integrity": "sha512-ldWuWSSkWbKOPjQMJoYVj9wLHcOniv7diyI5UAJ4XsBdtaFB0pKHQsqw/ItUma0VXGC7vB4E9fZjivmxur60aw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 OR MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/fast-xml-parser": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.3.tgz", + "integrity": "sha512-RKihhV+SHsIUGXObeVy9AXiBbFwkVk7Syp8XgwN5U3JV416+Gwp/GO9i0JYKmikykgz/UHRrrV4ROuZEo/T0ig==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT", + "dependencies": { + "strnum": "^1.1.1" + }, + "bin": { + "fxparser": "src/cli/cli.js" + } + }, + "node_modules/strnum": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", + "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/NaturalIntelligence" + } + ], + "license": "MIT" + } + } +} diff --git a/tools/join-backups/package.json b/tools/join-backups/package.json new file mode 100644 index 0000000..1bb54c7 --- /dev/null +++ b/tools/join-backups/package.json @@ -0,0 +1,21 @@ +{ + "name": "join-backups", + "version": "0.1.0", + "description": "CLI tool to join multiple SMS Backup XML files into a single merged backup", + "bin": { + "join-backups": "index.js" + }, + "scripts": { + "start": "node index.js", + "gui": "npx http-server gui -p 8081 -c-1", + "tauri:dev": "tauri dev", + "tauri:build": "tauri build" + }, + "private": true, + "dependencies": { + "fast-xml-parser": "^4.0.12" + }, + "devDependencies": { + "@tauri-apps/cli": "^2.9.6" + } +} \ No newline at end of file diff --git a/tools/join-backups/tauri/Cargo.toml b/tools/join-backups/tauri/Cargo.toml new file mode 100644 index 0000000..caa7ce1 --- /dev/null +++ b/tools/join-backups/tauri/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "join_backups_tauri" +version = "0.1.0" +edition = "2021" + +[dependencies] +# Match main project tauri version family +tauri = { version = "^2.9.0", features = ["api-all"] } diff --git a/tools/join-backups/tauri/src/main.rs b/tools/join-backups/tauri/src/main.rs new file mode 100644 index 0000000..0c8b396 --- /dev/null +++ b/tools/join-backups/tauri/src/main.rs @@ -0,0 +1,7 @@ +#![cfg_attr(all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows")] + +fn main() { + tauri::Builder::default() + .run(tauri::generate_context!()) + .expect("error while running tauri application"); +} diff --git a/tools/join-backups/tauri/tauri.conf.json b/tools/join-backups/tauri/tauri.conf.json new file mode 100644 index 0000000..576e60b --- /dev/null +++ b/tools/join-backups/tauri/tauri.conf.json @@ -0,0 +1,17 @@ +{ + "build": { + "beforeDevCommand": "npx http-server ../gui -p 8081 -c-1", + "devPath": "http://localhost:8081", + "distDir": "../gui" + }, + "package": { + "productName": "Join Backups", + "version": "0.1.0" + }, + "tauri": { + "bundle": { + "active": true, + "identifier": "dev.joinbackups" + } + } +} diff --git a/tsconfig.app.json b/tsconfig.app.json new file mode 100644 index 0000000..264f459 --- /dev/null +++ b/tsconfig.app.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "include": [ + "src/**/*.ts" + ], + "exclude": [ + "src/**/*.spec.ts" + ] +} diff --git a/tsconfig.json b/tsconfig.json index 6f300c5..590ef20 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,19 +1,26 @@ { "compileOnSave": false, "compilerOptions": { - "outDir": "./dist/out-tsc", - "sourceMap": true, - "declaration": false, - "moduleResolution": "node", - "emitDecoratorMetadata": true, + "strict": false, + "skipLibCheck": true, "experimentalDecorators": true, - "target": "es2015", - "typeRoots": [ - "node_modules/@types" - ], - "lib": [ - "es2017", - "dom" - ] - } + "importHelpers": true, + "target": "ES2022", + "module": "preserve" + }, + "angularCompilerOptions": { + "strictInjectionParameters": false, + "strictInputAccessModifiers": false, + "strictTemplates": false + }, + "files": [], + "references": [ + { + "path": "./tsconfig.app.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] } + diff --git a/tsconfig.spec.json b/tsconfig.spec.json new file mode 100644 index 0000000..4628775 --- /dev/null +++ b/tsconfig.spec.json @@ -0,0 +1,15 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": [ + "vitest/globals" + ] + }, + "include": [ + "src/**/*.d.ts", + "src/**/*.ts" + ] +} diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000..60f105d --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,14 @@ +import { defineConfig } from 'vitest/config'; + +export default defineConfig({ + test: { + globals: true, + environment: 'jsdom', + setupFiles: ['src/vitest.setup.ts'], + include: ['src/**/*.spec.ts'], + exclude: [ + 'src/**/*.component.spec.ts', + 'src/**/app.component.spec.ts' + ], + }, +});